OWIN 自宿主模式WebApi项目,WebApi层作为单独类库供OWIN调用
来源:互联网 发布:jsp编程技术课后答案 编辑:程序博客网 时间:2024/06/15 01:32
为什么我们需要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.Srv10 {11 class AppStart12 {13 static void Main(string[] args)14 {15 //string baseAddress = "http://localhost:3999/"; //localhost visit16 string baseAddress = "http://+:3999/"; //all internet environment visit 17 try18 {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 configuration35 class StartUp36 {37 public void Configuration(IAppBuilder appBuilder)38 {39 HttpConfiguration config = new HttpConfiguration();40 41 // Web API configuration and services42 //跨域配置 //need reference from nuget43 config.EnableCors(new EnableCorsAttribute("*", "*", "*"));44 //enabing attribute routing45 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 attributes56 //config.Filters.Add(new App.Web.Filters.ExceptionAttribute_DG());57 58 //new ClassRegisters(); //register ioc menbers59 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:5710 **/11 public class Test1Controller:ApiController12 {13 //access http://localhost:3999/api/Test1 get method14 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 method20 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 method25 public IHttpActionResult PutTest()26 {27 return Json(new { IsSuccess = true, Msg = "this is put method" });28 }29 //access http://localhost:3999/api/Test1 delete method30 public IHttpActionResult DeleteTest()31 {32 return Json(new { IsSuccess = true, Msg = "this is delete method" });33 }34 }35 }
这里我是用的是RESTFull风格的WebApi控制器接口。
然后我们可以进行试运行:
服务启动成功!
测试通过,我们可以尽情地探索后续开发步骤!
阅读全文
0 0
- OWIN 自宿主模式WebApi项目,WebApi层作为单独类库供OWIN调用
- OWIN webapi 环境搭建
- 基于ASP.NET WebAPI OWIN实现Self-Host项目实战
- 【7】.net WebAPI Owin OAuth 2.0 密码模式验证实例
- WebAPI OWIN认证引起的系列问题
- 使用owin不依赖iis 构建自承载的c# web服务器,支持ajax+html+webapi
- WebApi自宿主应用
- 基于OWIN WebAPI 使用OAuth授权服务【客户端模式(Client Credentials Grant)】
- 在WebApi中基于Owin OAuth使用授权发放Token
- webapi基于Microsoft.Owin.Security.OAuth的OAuth实现
- OWIN
- 使用OWIN 构建自宿主ASP.NET Web API 2
- 调用webapi
- webApi调用
- WebAPI
- webApi
- webapi
- WebAPi
- 51Nod 加农炮
- Oracle 的学习
- JAVA通过JS调用生成二维码
- 机器学习的未来属于 Linux 内核
- mysql事物的等级
- OWIN 自宿主模式WebApi项目,WebApi层作为单独类库供OWIN调用
- 洛谷Oj-八皇后-深度优先搜索
- 14、react之 组件的协同使用(组件的名字首字母必须大写)
- 集合框架 List,Set,Map和泛型
- [sicily] 1002. 等价二叉树
- Winform调用WebKitBrowser,基于chrome内核WebKit的浏览器控件
- 祝贺实验室的师兄夺得KDD2017的两项冠军,沾沾喜气
- 适配器模式
- 六、swift3.0类的使用