设为首页 收藏本站
查看: 696|回复: 0

[经验分享] WebApi的windows服务之路

[复制链接]

尚未签到

发表于 2017-6-28 19:01:20 | 显示全部楼层 |阅读模式
开发Web Api的接口在windows服务中实现,需要先安装4个组件,分别如下:
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.SelfHost" version="5.2.3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
我是用vs2015的开发工具来做此件事情的,先上项目结构图:
   DSC0000.png
  图1
  先分别讲一下,各个项目的职能
  第一、YBaseFramework.YBF.WebApiEngine 此项目是具体实现 WebApi的引擎,我会借一个工具来实,具体代码如下:
  /// <summary>
  /// 开始启动服务
  /// </summary>
  /// <returns></returns>
  public bool Start()
  {
  _context.Info("执行启动");
  _context.DebugFormat(GetType(), "WebApiEngine {0} Starting... ", Utils.GetVersion());
  try
  {
  var config = new HttpSelfHostConfiguration(BaseConfig.Hosts);
  XmlDocument xmlDocument = new XmlDocument();
  xmlDocument.Load("YBF.WebApiServiceController.exe.config");
  XmlNodeList nodes = xmlDocument.SelectNodes("configuration/preLoadedAssemblies/add");
  foreach (XmlNode n in nodes)
  {
  string dllname = n.Attributes["assemblyName"].InnerText.Trim();//其它属性类似获取 这里输出Conn  
  string localhostdll = System.AppDomain.CurrentDomain.BaseDirectory + "\\" + dllname;
  string projectCode = BaseConfig.GetDllProCode(dllname);//项目缩写代码
  Assembly dllFile = Assembly.UnsafeLoadFrom(localhostdll);
  Type[] classType = dllFile.GetTypes();
  foreach (var item in classType)
  {
  if (item.FullName.ToLower().IndexOf("dbservices") > 0)
  {
  string[] nameSpaceNames = item.FullName.Split('.');
  string module = nameSpaceNames[2].ToLower().Replace("dbservices", "");//模块名称
  string nameSpaceName = nameSpaceNames[0] + "." + nameSpaceNames[1] + "." + nameSpaceNames[2];
  config.Routes.MapHttpRoute(
                                  projectCode + module, projectCode + "/" + module + "/{controller}/{action}" + BaseConfig.Suffix,
                                  new
                                  {
                                      action = RouteParameter.Optional,
                                      id = RouteParameter.Optional,
                                      namespaceName = new string[1] { nameSpaceName }
                                  });
  }
  }
  }
  server = new HttpSelfHostServer(config);
  server.Configuration.Services.Replace(typeof(IAssembliesResolver), new ExtendedDefaultAssembliesResolver());
  server.OpenAsync().Wait();
  server.Configuration.Services.Replace(typeof(IHttpControllerSelector),
  new NamespaceHttpControllerSelector(server.Configuration));
  if (BaseConfig.OutputformatIsJson)
  {
  #region  接口返回结果格式
  var jsonFormatter = new JsonMediaTypeFormatter();
  server.Configuration.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));
  #endregion  接口返回结果格式
  }
  _context.Info("WebApi服务已开启,已成功监控!");
  return true;
  }
  catch (Exception ex)
  {
  server.CloseAsync().Wait();
  server.Dispose();
  _context.ErrorFormat(GetType(), "WebApi服务已失败,原因{0}!",ex.Message);
  return false;
  }
  }
  BaseSetting的文件夹为一些基础配置与实现,如动态加载dll文件等;
  Helper的文件夹为接中返回结果的类型定义类;
  第二、YBaseFramework.YBF.PublicConfig 此项目为公共信息配置,有两个文件夹要注意:
  Helper文件夹中的ConstHelper类是一些常量的定义,ParamVerificationHelper类是表单参数的验证;
  RestResult文件夹接口返回的类;
DSC0001.png

  图2
  public class Response
  {
  public int status { get; set; }
  public string msg { get; set; }
  public object data { get; set; }
  }
  public class PageData
  {
  public int totalnum { get; set; }
  public int totalpage { get; set; }
  public int currentpage { get; set; }
  public object info { get; set; }
  }
  第三、YBaseFramework.YBF.HelloWorldApiServices此项目为WebApi具体实现,目前HelloWorld为名,仅是一个demo,文件结构如下:
DSC0002.png

  图3
  在上面的引擎中,我已经将路由的定义,标红色文字,所以这里的DemoDBServices的文件夹的命名就是必须以DBServices结束,控制器的命令也是以Controller结束,只好mvc中的控制器命名一样;
  [HttpGet]
  public Response GetUsers()
  {
  try
  {
  var res = new Response();
  res.status = 0;
  res.msg = "success";
  var data = new PageData();
  data.currentpage = 1;
  data.totalnum = 100;
  data.totalpage = 10;               
  var infos = new List<dynamic>();
  for (int i = 1; i < 1000; i++)
  {
  infos.Add(new { Name = "abc" + i.ToString(), ID = i });
  }
  data.info = infos;
  res.data = data;
  _context.InfoFormat(GetType(), "HelloWorldController {0} 处理数据条数:{1}", Utils.GetVersion(), infos.Count);
  return res;
  }
  catch (Exception ex)
  {
  _context.ErrorFormat(GetType(), "HelloWorldController {0} 错误原因:{1}", Utils.GetVersion(),ex.Message);
  return null;
  }
  }
  /// <summary>
  /// post测试验证登录
  /// </summary>
  /// <param name="memberModel"></param>
  /// <returns></returns>
  [HttpPost]
  public Response LoginCheck([FromBody]MEMBERModel memberModel)
  {
  var obj =  RequestContext.RouteData.Values;//取路由的信息
  string Url = RequestContext.Url.Request.RequestUri.LocalPath;
  Response res = ParamVerificationHelper.CheckParVerLegal<MEMBERModel>(Url, memberModel);
  if (res != null)
  {
  return res;
  }
  string msg = string.Empty;
  string state = "0";
  if(string.IsNullOrWhiteSpace(memberModel.USERNAME))
  {
  state = "3";
  }
  else if(string.IsNullOrWhiteSpace(memberModel.PASSWORD))
  {
  state = "2";
  }
  switch (state)
  {
  case "0":
  msg = "登录成功";
  break;
  case "1":
  msg = "审核不通过";
  break;
  case "2":
  msg = "密码不正确";
  break;
  case "3":
  msg = "帐号不存在";
  break;
  }
  object data = null;
  if (state == "0")
  {
  data =
  new
  {
  username = memberModel.USERNAME,
  phone = "13761085465-app",
  email = "baishi_12@163.com",
  image =
  string.IsNullOrEmpty("")
  ? "http://www.gjw.com/image/face/1.jpg"
  : "http://img0.gjw.com/face/" + "",
  name = "baishi",
  gender = "男" == "女" ? "2" : "1",
  password = ""
  };
  }
  var response = new Response { status = state == "0" ? 0 : 1, msg = msg, data = data };
  return response;
  }
  在DemoModel文件夹中是定义了具体接口所要使用到的实体:
  ParamModel.cs为接口接收参数部分
  /// <summary>
  /// 前台会员信息
  /// </summary>
  public class MEMBERModel
  {
  public string USERNAME { get; set; }
  public string PASSWORD { get; set; }
  public string vastr { get; set; }
  }
  /// <summary>
  /// 商品信息
  /// </summary>
  public class PRODUCTModel
  {
  public string vastr { get; set; }
  }
  Product.cs
  public class Product
  {
  public string Name { get; set; }
  public string Price { get; set; }
  }
  以上三个大步,就可以实现了两个接口,下面我们就以Demo的操作图片说明。
  第四、发布测试接口
  A、接口测试配置文件:
  <root>
  <Interface name="GetUsers" url="http://localhost:3721/hw/demo/HelloWorld/getusers.html" params="" type="get" remark="取用户列表接口说明"></Interface>
  <Interface name="Getlist" url="http://localhost:3721/hw/demo/HelloWorld/getlist.html" params="" type="get" remark="商品列表接口说明"></Interface>
  <Interface name="LoginCheck" url="http://localhost:3721/hw/demo/HelloWorld/LoginCheck1.html" params="USERNAME={0}&PASSWORD={1}" type="post" remark="登录接口说明"></Interface>
  </root>
  B、接口实体实现宿主程序,如图:
DSC0003.png

  图4
  C、测试接口结果
DSC0004.png

  图5
DSC0005.png

  图6
  到此一个web api接口的实现与测试示例,已经完成了,实验Demo会提供下载可以自己去测试;
  WebAPI示例: 下载
  后续还是讲wcf restful的windows服务之路。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-389085-1-1.html 上篇帖子: Windows下将nginx安装为服务运行 下篇帖子: Windows 10 使用C#如何将IE设置为默认浏览器
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表