窝窝插件 发表于 2017-6-28 19:01:20

WebApi的windows服务之路

开发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的开发工具来做此件事情的,先上项目结构图:
  
  图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.ToLower().Replace("dbservices", "");//模块名称
  string nameSpaceName = nameSpaceNames + "." + nameSpaceNames + "." + nameSpaceNames;
  config.Routes.MapHttpRoute(
                                projectCode + module, projectCode + "/" + module + "/{controller}/{action}" + BaseConfig.Suffix,
                                new
                                {
                                      action = RouteParameter.Optional,
                                      id = RouteParameter.Optional,
                                      namespaceName = new string { 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文件夹接口返回的类;

  图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,文件结构如下:

  图3
  在上面的引擎中,我已经将路由的定义,标红色文字,所以这里的DemoDBServices的文件夹的命名就是必须以DBServices结束,控制器的命令也是以Controller结束,只好mvc中的控制器命名一样;
  
  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>
  
  public Response LoginCheck(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、接口实体实现宿主程序,如图:

  图4
  C、测试接口结果

  图5

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