ASP.NET WEB API的服务托管(Self-HOST)

如果我们想对外发布RESTful API,可以基于ASP.NET来构建Restful APIs,但需要部署IIS吗?答案是不必。你可以把它托管到一个Windows Service。具体如何把WEB API自托管到Windows Service可以参考这一文章:Self-Host a Web API (HttpSelfHostServer) (C#). 基本上照着一步步做就行了。例子里是基于Windows Console Application,同样可以Self-Host到Windows Service.

问题在于如何把Controllers从Windows Service分离?可以使用autoFac,本文具体从这展开。

使用autoFac分离Controllers

autoFac是一个.NET IoC容器框架,这里我们用来分离Controllers,也就是说,我们把MVC的控制器Controllers放到独立的一个工程(Project),然后在Windows Service里面自托管(Self-Host)RESTful APIs。部署的时候只要部署windows service即可,不需要IIS,外部一样可以调用我们的RESTful APIs. 需要做的就是: 1. 引用autoFac 2. 注册Controllers 3. 设置DependencyResolver。好,我们新建一个project,类型是类库dll。添加引用:System.Web.Http;添加一个Controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Newtonsoft.Json;
 
namespace myCompany
{
    public class GroupController : ApiController, IGroupController
    {
        public HttpResponseMessage Update(HttpRequestMessage request)
        {
            Model model = null;
            var body = "";
            var valid = true;
            var result = new response { success = true, message = "" };
            HttpResponseMessage response;
 
            try
            {
                body = request.Content.ReadAsStringAsync().Result;
                /*
                 * According to the content type (text / json / xml), deserialize the request body
                 */
                model = Deserialize(body,
                    ModelUtility.GetMediaType(request.Content.Headers.ContentType.ToString()));
 
                if (model == null)
                    valid = false;
            }
            catch (Exception e)
            {
                valid = false;
            }
 
            if (!valid)
            {
                response = BuildFailureResponse(string.Format(
                    "Failure during parsing the request [{0}]", body));
            }
            else
            {
                 response = Request.CreateResponse<response>(HttpStatusCode.OK, result);
            }
             
            return response;
        }
 
        private static Model Deserialize(string data, MediaTypes type)
        {
            switch (type)
            {
                case MediaTypes.HTML:
                    break;
                case MediaTypes.JSON:
                    return JsonConvert.DeserializeObject<Model>(data);
                case MediaTypes.TEXT:
                    return new Model
                    {
                        name = ModelUtility.ParseText(data, "name"),
                        status = ModelUtility.ParseText(data, "status")
                    };
                case MediaTypes.XML:
                    return Utility.XmlSerilizer.Deserialize<Model>(data);
                case MediaTypes.UNKNOWN:
                    break;
                default:
                    break;
            }
            return null;
        }
 
        private HttpResponseMessage BuildFailureResponse(string message)
        {
            var result = new response { success = false, message = message };
            return Request.CreateResponse<response>(HttpStatusCode.BadRequest, result);
        }
 
    }
     
}

上面那个控制器可以处理RESTful API涉及group的请求。具体下面再谈。

回到我们已经创建Self-Host的Windows Service项目,里面添加引用Autofac.dll和Autofac.Integration.WebApi.dll。此外,可能还需要一些引用,我这里的列表如下:

ASP.NET WEB API的服务托管(Self-HOST)

然后在Windows Service项目里面添加一个类,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System.Reflection;
using System.Web.Http;
using Autofac;
using Autofac.Integration.WebApi;
 
namespace myCompany
{
    public class AutofacWebAPI
    {
        public static void Initialize(HttpConfiguration config)
        {
            config.DependencyResolver = new AutofacWebApiDependencyResolver(
                RegisterServices(new ContainerBuilder())
            );
        }
 
        private static IContainer RegisterServices(ContainerBuilder builder)
        {
            builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).PropertiesAutowired();
 
            builder.RegisterType<GroupController>().As<IGroupController>();
 
            return builder.Build();
        }
    }
}

主要就是用来aufoFac初始化和注册类型。然后在Windows service里面调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public partial class Service : ServiceBase
{
       private HttpSelfHostServer _server;
       private readonly HttpSelfHostConfiguration _config;
        
       public Service()
       {
           InitializeComponent();
            
           _config = new HttpSelfHostConfiguration(_serviceAddress);
           _config.Routes.MapHttpRoute("DefaultApi",
               "notifications/{controller}/{id}",
               new { id = RouteParameter.Optional });
       }
        
       protected override void OnStart(string[] args)
       {
    /* Start self-host Web API */
               AutofacWebAPI.Initialize(GlobalConfiguration.Configuration);
               _server = new HttpSelfHostServer(_config);
               _server.OpenAsync();
      }
}

就这么简单。此外,你还可以用其他的DependencyResolver方式,具体参考autoFac官方文档:https://code.google.com/p/autofac/wiki/WebApiIntegration

最后如何测试呢?

HTTP POST http://localhost:8080/notifications/group/update

post body (text/plain): name=abc&status=CANCELLED
post body (application/json): "{\"name\":\"abc\",\"status\":\"CANCELLED\"}";
post body (application/xml):
      @"<myc:root xmlns:myc=""http://api.abc.com/Platform/1.0"">
         <myc:name>abc</myc:name>
         <myc:status>CANCELLED</myc:status>
      </myc:root>";

看不懂的,可看代码。支持text/json/xml多种参数格式。RESTful API测试可以用Chrome插件:Postman REST Client

ASP.NET WEB API的服务托管(Self-HOST)

上一篇:docker-maven-plugin 打包镜像及命令解释_08


下一篇:SSM框架复习