OWIN 自宿主模式WebApi项目,WebApi层作为单独类库供OWIN调用

为什么我们需要OWIN

过去,IIS作为.NET开发者来说是最常用的Web Server(没有之一),源于微软产品的紧耦合关系,我们不得不将Website、Web Application、Web API等部署在IIS上,事实上在2010年前并没有什么不妥,但随着近些年来Web的发展,特别是移动互联网飞速发展,IIS作为Web Server已经暴露出他的不足了。主要体现在两个方面,ASP.NET (System.Web)紧耦合IIS,IIS紧耦合OS,这就意味着,我们的Web Framework必须部署在微软的操作系统上,难以跨平台。

...

OWIN是什么?在本文里面就不进行赘述,网上有很多介绍OWIN的信息以及优缺点的博文,这里可以给几个链接大家进行自行参考:

1、http://www.cnblogs.com/dudu/p/what-is-owin.html

2、http://blog.csdn.net/hk_5788/article/details/51607211

..

下面我们重点介绍我在搭建OWIN自宿主平台的过程,对于我是学习的过程,对于想要接触他的大家来说,也是一种帮助。

很多人搭建的OWIN+WebApi项目都是写在一个项目中的,我个人为了代码的隔离,将控制器层写在了另外一个项目中,这样有助于后期大型框架的形成。

下面是搭建步骤:

1、首先新建一个控制台应用程序和一个.NETFramework类库项目,控制台引用类库项目。

项目结构如下图所示:

OWIN.WebApi WebApi层

OWIN.WebApi.Sv WebApi服务层,将要作为启动项!

2、控制台项目使用NuGet引用需要的类库:

  OWIN

  Microsoft.Owin.Hosting

  Microsoft.Owin.Host.HttpListener

  Microsoct.AspNet.WebApi.Owin

  这里需要手动从WebApi项目里面找到System.Web.Web,System.Net.Http等Web类库进行引用。

  OWIN.WebApi.Srv层的引用情况(我这里有跨域配置,不需要的请忽略)

  

  在OWIN.WebApi层,我们需要同样引用Web的类库,我们才可以在WebApi项目控制器层继承自ApiController

   OWIN.WebApi层的引用情况(我这里有跨域配置,不需要的请忽略)

  

3、因为WebApi层要分开类库项目写,所以这里比一般的OWIN要多一些配置,在我项目的OWIN.WebApi层的config目录下,我新建了一个Global.cs类,里面的代码是对控制器的解析,代码展示如下:

  1 using System.Web.Http;
  2 using System.Web.Http.Dispatcher;
  3 using System;
  4 using System.Collections.Concurrent;
  5 using System.Collections.Generic;
  6 using System.Linq;
  7 using System.Net;
  8 using System.Net.Http;
  9 using System.Web.Http.Controllers;
 10
 11 namespace OWIN.WebApi.config
 12 {
 13     public class WebApiApplication : System.Web.HttpApplication
 14     {
 15         protected void Application_Start()
 16         {
 17             //ignore the xml return it`s setting let json return only
 18             GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
 19             GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
 20
 21             GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
 22             new WebApiControllerSelector(GlobalConfiguration.Configuration));
 23         }
 24     }
 25     /// <summary>
 26     /// the WebApiControllerSelector
 27     /// author:qixiao
 28     /// time:2017-1-31 19:24:32
 29     /// </summary>
 30     public class WebApiControllerSelector : DefaultHttpControllerSelector
 31     {
 32         private const string NamespaceRouteVariableName = "Namespace";
 33         private readonly HttpConfiguration _configuration;
 34         private readonly Lazy<ConcurrentDictionary<string, Type>> _apiControllerCache;
 35
 36         public WebApiControllerSelector(HttpConfiguration configuration)
 37             : base(configuration)
 38         {
 39             _configuration = configuration;
 40             _apiControllerCache = new Lazy<ConcurrentDictionary<string, Type>>(
 41                 new Func<ConcurrentDictionary<string, Type>>(InitializeApiControllerCache));
 42         }
 43
 44         private ConcurrentDictionary<string, Type> InitializeApiControllerCache()
 45         {
 46             IAssembliesResolver assembliesResolver = this._configuration.Services.GetAssembliesResolver();
 47             var types = this._configuration.Services.GetHttpControllerTypeResolver()
 48                 .GetControllerTypes(assembliesResolver).ToDictionary(t => t.FullName, t => t);
 49
 50             return new ConcurrentDictionary<string, Type>(types);
 51         }
 52
 53         public IEnumerable<string> GetControllerFullName(HttpRequestMessage request, string controllerName)
 54         {
 55             object namespaceName;
 56             var data = request.GetRouteData();
 57             IEnumerable<string> keys = _apiControllerCache.Value.ToDictionary<KeyValuePair<string, Type>, string, Type>(t => t.Key,
 58                     t => t.Value, StringComparer.CurrentCultureIgnoreCase).Keys.ToList();
 59
 60             if (!data.Values.TryGetValue(NamespaceRouteVariableName, out namespaceName))
 61             {
 62                 return from k in keys
 63                        where k.EndsWith(string.Format(".{0}{1}", controllerName,
 64                        DefaultHttpControllerSelector.ControllerSuffix), StringComparison.CurrentCultureIgnoreCase)
 65                        select k;
 66             }
 67
 68             string[] namespaces = (string[])namespaceName;
 69             return from n in namespaces
 70                    join k in keys on string.Format("{0}.{1}{2}", n, controllerName,
 71                    DefaultHttpControllerSelector.ControllerSuffix).ToLower() equals k.ToLower()
 72                    select k;
 73         }
 74
 75         public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
 76         {
 77             Type type;
 78             if (request == null)
 79             {
 80                 throw new ArgumentNullException("request");
 81             }
 82             string controllerName = this.GetControllerName(request);
 83             if (string.IsNullOrEmpty(controllerName))
 84             {
 85                 throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,
 86                     string.Format("No route providing a controller name was found to match request URI ‘{0}‘", new object[] { request.RequestUri })));
 87             }
 88             IEnumerable<string> fullNames = GetControllerFullName(request, controllerName);
 89             if (fullNames.Count() == 0)
 90             {
 91                 throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,
 92                         string.Format("No route providing a controller name was found to match request URI ‘{0}‘", new object[] { request.RequestUri })));
 93             }
 94
 95             if (this._apiControllerCache.Value.TryGetValue(fullNames.First(), out type))
 96             {
 97                 return new HttpControllerDescriptor(_configuration, controllerName, type);
 98             }
 99             throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,
100                 string.Format("No route providing a controller name was found to match request URI ‘{0}‘", new object[] { request.RequestUri })));
101         }
102     }
103 }

4、在OWIN.WebApi.Srv层里面新建AppStart.cs类,并且写如下代码:

 1 using Microsoft.Owin.Hosting;
 2 using System;
 3 using Owin;
 4 using System.Web.Http;
 5 using System.Web.Http.Dispatcher;
 6 using QX_Frame.App.WebApi.Extends;
 7 using System.Web.Http.Cors;
 8
 9 namespace OWIN.WebApi.Srv
10 {
11     class AppStart
12     {
13         static void Main(string[] args)
14         {
15             //string baseAddress = "http://localhost:3999/";    //localhost visit
16             string baseAddress = "http://+:3999/";              //all internet environment visit
17             try
18             {
19                 WebApp.Start<StartUp>(url: baseAddress);
20                 Console.WriteLine("BaseIpAddress is " + baseAddress);
21                 Console.WriteLine("\nApplication Started !");
22             }
23             catch (Exception ex)
24             {
25                 Console.WriteLine(ex.ToString());
26             }
27
28             for (;;)
29             {
30                 Console.ReadLine();
31             }
32         }
33     }
34     //the start up configuration
35     class StartUp
36     {
37         public void Configuration(IAppBuilder appBuilder)
38         {
39             HttpConfiguration config = new HttpConfiguration();
40
41             // Web API configuration and services
42             //跨域配置 //need reference from nuget
43             config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
44             //enabing attribute routing
45             config.MapHttpAttributeRoutes();
46             // Web API Convention-based routing.
47             config.Routes.MapHttpRoute(
48                 name: "DefaultApi",
49                 routeTemplate: "api/{controller}/{id}",
50                 defaults: new { id = RouteParameter.Optional },
51                 namespaces: new string[] { "OWIN.WebApi" }
52             );
53             config.Services.Replace(typeof(IHttpControllerSelector), new OWIN.WebApi.config.WebApiControllerSelector(config));
54
55             //if config the global filter input there need not write the attributes
56             //config.Filters.Add(new App.Web.Filters.ExceptionAttribute_DG());
57
58             //new ClassRegisters(); //register ioc menbers
59
60             appBuilder.UseWebApi(config);
61         }
62     }
63 }

里面对地址进行了配置,当然可以根据需求自行配置,显示信息也进行了适当的展示,需要说明的一点是,我这里进行了跨域的配置,没有配置或者是不需要的请注释掉并忽略!

这里需要注意的是第53行,这里引用的是刚才的OWIN.WebApi层的Global.cs里面的类,请对照上述两段代码进行查找。

这行是关键,有了这行,程序才可以扫描到WebApi层的Controller。好了,我们进行Controller的书写。

5、在OWIN.WebApi层进行控制器类的编写,这里随意,我只在这里列出我的例子。

 1 using QX_Frame.App.WebApi;
 2 using QX_Frame.Helper_DG;
 3 using System.Web.Http;
 4
 5 namespace OWIN.WebApi
 6 {
 7     /*
 8      * author:qixiao
 9      * time:2017-2-27 10:32:57
10      **/
11     public class Test1Controller:ApiController
12     {
13         //access http://localhost:3999/api/Test1  get method
14         public IHttpActionResult GetTest()
15         {
16             //throw new Exception_DG("login id , pwd", "argumets can not be null", 11111, 2222);
17             return Json(new { IsSuccess = true, Msg = "this is get method" });
18         }
19         //access http://localhost:3999/api/Test1  post method
20         public IHttpActionResult PostTest(dynamic queryData)
21         {
22             return Json(new { IsSuccess = true, Msg = "this is post method",Data=queryData });
23         }
24         //access http://localhost:3999/api/Test1  put method
25         public IHttpActionResult PutTest()
26         {
27             return Json(new { IsSuccess = true, Msg = "this is put method" });
28         }
29         //access http://localhost:3999/api/Test1  delete method
30         public IHttpActionResult DeleteTest()
31         {
32             return Json(new { IsSuccess = true, Msg = "this is delete method" });
33         }
34     }
35 }

这里我是用的是RESTFull风格的WebApi控制器接口。

然后我们可以进行试运行:

服务启动成功!

测试通过,我们可以尽情地探索后续开发步骤!

时间: 2024-11-10 00:56:55

OWIN 自宿主模式WebApi项目,WebApi层作为单独类库供OWIN调用的相关文章

ASP.NET WebAPI 项目示例(增删改查)

1.WebApi是什么 ASP.NET Web API 是一种框架,用于轻松构建可以由多种客户端(包括浏览器和移动设备)访问的 HTTP 服务.ASP.NET Web API 是一种用于在 .NET Framework 上构建 RESTful 应用程序的理想平台. 可以把WebApi看成Asp.Net项目类型中的一种,其他项目类型诸如我们熟知的WebForm项目,Windows窗体项目,控制台应用程序等. WebApi类型项目的最大优势就是,开发者再也不用担心客户端和服务器之间传输的数据的序列化

第一个WebAPI项目

(1)新建一个ASP.NET MVC项目,取名为:MyMvcWebAPIDemo,项目类型选择WebAPI. (2)在Models中新增一个类,取名为:Product,作为我们要测试的实体模型. 1 2 3 4 5 6 7 public class Product { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Pr

1、创建及配置WebApi项目

一.项目背景 前端时间由于公司业务需求,需要本部门提供接口供其访问调用,而这个任务刚好落到我头上,于是开始着手学习和掌握Api开发,并参考三层架构的设计思想将Api分成Model.Dal.BLL.UI四层.在开发之初,经常遇到不明白的地方,比如不明白HttpGet.HttpPost.HttpPut和HttpDelete的应用场景以及为什么别人使用IHttpActionResult作为接口的返回类型,后来查阅相关资料后,慢慢地理解了,现在,对于WebApi已有了初步的了解,虽说还待继续深化理解,但

ASP.NET Core WebAPI 开发-新建WebAPI项目 转

转 http://www.cnblogs.com/linezero/p/5497472.html ASP.NET Core WebAPI 开发-新建WebAPI项目 ASP.NET Core WebAPI 开发-新建WebAPI项目, ASP.NET Core 1.0 RC2 即将发布,我们现在来学习一下 ASP.NET Core WebAPI开发. 网上已经有泄露的VS2015 Tooling,需要VS2015 Update 2. .NET Core 1.0.0 RC2 SDK Preview

ASP.NET Core WebAPI 开发-新建WebAPI项目

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 ASP.NET Core WebAPI 开发-新建WebAPI项目, ASP.NET Core 1.0 RC2 即将发布,我们现在来学习一下 ASP.NET Core WebAPI开发. 网上已经有泄露的VS2015 Tooling,需要VS2

MVC4下创建一个webapi项目里面怎么开启session会话

由于mvc4里的webapi项目,创建时是没有开启session的权限的,这个要自己去开启,开启方式如下: 1.在全局文件Global.asax.cs里重写 Init()方法: public override void Init() { this.PostAuthenticateRequest += MvcApplication_PostAuthenticateRequest; base.Init(); } private void MvcApplication_PostAuthenticate

在.net core 的webapi项目中将对象序列化成json

问题:vs2017 15.7.6创建一个基于.net core 2.1的webapi项目,默认生成的控制器继承自ControllerBase类 在此情况下无法使用Json()方法 将一个对象转成json 解决方案:将控制器继承的类 改为Controller 此时可以使用json()方法 将对象直接转成json. 原文地址:https://www.cnblogs.com/wholeworld/p/9701144.html

如何在启用JWT Token授权的.NET Core WebApi项目中下载文件

背景 前几天,做项目的时候遇到一个文件下载的问题.当前系统是一个前后端分离的项目,前端是一个AngularJs项目, 后端是一个.NET Core WebApi项目.后端的Api项目使用了Jwt Token授权,所以每个Api请求都需要传递一个Bearer Token. 这一切都看起来理所当然,但是当需要从WebApi下载文件的时候,出现了问题.以前下载文件的时候,我们可以在Javascript中使用window.open('[文件下载Api]')的方式下载文件,但是这个方法不能接收Bearer

在WebApi项目里使用MiniProfiler并且分析 Entity Framework Core

在WebApi项目里使用MiniProfiler并且分析 Entity Framework Core 一.安装配置MiniProfiler 在现有的ASP.NET Core MVC WebApi 项目里,通过Nuget安装MiniProfiler: Install-Package MiniProfiler.AspNetCore.Mvc MiniProfiler.EntityFrameworkCore 当然也可以通过Nuget Package Manager可视化工具安装 接下来就是如何配置和使用