前言

默认情况下,微软提供的MVC框架模板中,WebAPI路由是不支持Namespace参数的。这导致一些比较大型的项目,无法把WebApi分离到单独的类库中。

本文将提供解决该问题的方案。

微软官方曾经给出过一个关于WebAPI支持Namespace的扩展,其主要内容就是自定义实现了IHttpControllerSelector接口,通过路由配置时替换掉MVC中自带的DefaultHttpControllerSelector达到WebAPI支持Namespace的目的。但是经过我的测试,效果并不好。这就就不贴微软官方的源码了。

解决方案

下面我介绍一下我的解决方案。

首先看一下我自定义的目录结构,如下图:

首先定义一个类,名字可以随意,我这里命名为ZhuSirNamespaceHttpControllerSelector,他继承自MVC框架默认的DefaultHttpControllerSelector类,该继承类主要目的是在请求URI到达WebAPI路由时检索我们指定的命名空间的WebAPI控制器。下面是ZhuSirNamespaceHttpControllerSelector类的源代码,可直接复制到你自己的项目中就可以用:

/// <summary>/// 扩展自DefaultHttpControllerSelector类的控制器选择器,目前在用/// </summary>public class ZhuSirNamespaceHttpControllerSelector : DefaultHttpControllerSelector{private const string NamespaceRouteVariableName = "namespaces";private readonly HttpConfiguration _configuration;private readonly Lazy<ConcurrentDictionary<string, Type>> _apiControllerCache;public ZhuSirNamespaceHttpControllerSelector(HttpConfiguration configuration): base(configuration){_configuration = configuration;_apiControllerCache = new Lazy<ConcurrentDictionary<string, Type>>(new Func<ConcurrentDictionary<string, Type>>(InitializeApiControllerCache));}private ConcurrentDictionary<string, Type> InitializeApiControllerCache(){IAssembliesResolver assembliesResolver = this._configuration.Services.GetAssembliesResolver();var types = this._configuration.Services.GetHttpControllerTypeResolver().GetControllerTypes(assembliesResolver).ToDictionary(t => t.FullName, t => t);return new ConcurrentDictionary<string, Type>(types);}public IEnumerable<string> GetControllerFullName(HttpRequestMessage request, string controllerName){object namespaceName;var data = request.GetRouteData();IEnumerable<string> keys = _apiControllerCache.Value.ToDictionary<KeyValuePair<string, Type>, string, Type>(t => t.Key,t => t.Value, StringComparer.CurrentCultureIgnoreCase).Keys.ToList();if (!data.Values.TryGetValue(NamespaceRouteVariableName, out namespaceName)){return from k in keyswhere k.EndsWith(string.Format(".{0}{1}", controllerName,DefaultHttpControllerSelector.ControllerSuffix), StringComparison.CurrentCultureIgnoreCase)select k;}string[] namespaces = (string[])namespaceName;return from n in namespacesjoin k in keys on string.Format("{0}.{1}{2}", n, controllerName,DefaultHttpControllerSelector.ControllerSuffix).ToLower() equals k.ToLower()select k;}public override HttpControllerDescriptor SelectController(HttpRequestMessage request){Type type;if (request == null){throw new ArgumentNullException("request");}string controllerName = this.GetControllerName(request);if (string.IsNullOrEmpty(controllerName)){throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,string.Format("无法通过API路由匹配到您所请求的URI '{0}'",new object[] { request.RequestUri })));}IEnumerable<string> fullNames = GetControllerFullName(request, controllerName);if (fullNames.Count() == 0){throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,string.Format("无法通过API路由匹配到您所请求的URI '{0}'",new object[] { request.RequestUri })));}if (this._apiControllerCache.Value.TryGetValue(fullNames.First(), out type)){return new HttpControllerDescriptor(_configuration, controllerName, type);}throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,string.Format("无法通过API路由匹配到您所请求的URI '{0}'",new object[] { request.RequestUri })));}}

   第二步,需要我们配置WebAPI路由设置,添加{ namespaces }片段变量,同时也可以直接为其设置默认值,然后替换掉原MVC框架中的DefaultHttpControllerSelector选额器为我们之前扩展的ZhuSirNamespaceHttpControllerSelector选额器。这里需要注意片段变量的变量名namespaces一定要与我们ZhuSirNamespaceHttpControllerSelector中定义的NamespaceRouteVariableName字符串常量的值一致。下面贴出WebApiConfig的源码:
public static class WebApiConfig{public static void Register(HttpConfiguration config){//配置检查Api控制后缀为ApiController//var suffix = typeof(MicrosoftNamespaceHttpControllerSelector)//    .GetField("ControllerSuffix", BindingFlags.Static | BindingFlags.Public);//if (suffix != null)//{//    suffix.SetValue(null, "ApiController");//}// Web API 配置和服务// 将 Web API 配置为仅使用不记名令牌身份验证。config.SuppressDefaultHostAuthentication();config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));// 对 JSON 数据使用混合大小写。config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();// Web API 路由config.MapHttpAttributeRoutes();config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{id}/{namespaces}",defaults: new { id = RouteParameter.Optional ,namespaces = new[] { "ZhuSir.HMS.WebApi.ApiControllers" }  });config.Services.Replace(typeof(IHttpControllerSelector), new ZhuSirNamespaceHttpControllerSelector(config));}}

如上源码。我们替换了原MVC框架的DefaultHttpControllerSelector为ZhuSirNamespaceHttpControllerSelector,并且指定了默认的namespaces为ZhuSir.HMS.WebApi.ApiControllers。大体意思就是当URL为 http://XXX/api/testApi时,WebApi路由将在ZhuSir.HMS.WebApi.ApiControllers命名空间下寻找名称为testApi的WebAPI控制器的Get方法。

当然,WebAPI控制器除了集成字ApiController意外还要注意命名规范,都需要以Controller结尾,为了不让API控制器与MVC控制器重名,我都以ApiController结尾。下面贴出testAPI的源码:

namespace ZhuSir.HMS.WebApi.ApiControllers
{public class TestApiController : ApiController{[HttpGet]public string Gettest(){return "测试数据";}}
}

测试

程序Debug,录入URL: http://localhost:4541/api/TestApi,得到如下结果:

可以看出,WebAPI路由成功访问到了其他类库中的WebAPI控制器。

希望本文对你能有所帮助,如果转载请注明出处:http://www.cnblogs.com/smallprogram/p/5673066.html

作者:smallprogram
出处:http://www.cnblogs.com/smallprogram/p/5673066.html
感谢您的阅读。喜欢的、有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力。欢迎转载!另外,文章在表述和代码方面如有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论!

分类: Asp.NET MVC

转载于:https://www.cnblogs.com/webenh/p/7512709.html

asp.net MVC5为WebAPI添加命名空间的支持相关推荐

  1. [Asp.net MVC]Asp.net MVC5系列——添加数据

    目录 概述 显示添加数据时所用表单 处理HTTP-POST 总结 系列文章 [Asp.net MVC]Asp.net MVC5系列--第一个项目 [Asp.net MVC]Asp.net MVC5系列 ...

  2. ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试

    ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试 1:ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-WebApi与Unity注入 使用Uni ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(65)-MVC WebApi 用户验证 (1)

    系列目录 前言: WebAPI主要开放数据给手机APP,其他需要得知数据的系统,或者软件应用,所以移动端与系统的数据源往往是相通的. Web 用户的身份验证,及页面操作权限验证是B/S系统的基础功能, ...

  4. ASP.NET MVC5 高级教程 学习笔记

    // 本应用是ASP.NET MVC5 高级教程学习产物 // 2015-07-23 // 第一章 入门 // 第二章 控制器 // 第三章 视图 1.Install-Package Wrox.Pro ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库  您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB  升级后界面效果如下: 日程管理   http:// ...

  6. ASP.NET MVC5+EF6+EasyUI 后台管理系统(51)-系统升级

    系统很久没有更新内容了,期待已久的更新在今天发布了,最近花了2个月的时间每天一点点,从原有系统 MVC4+EF5+UNITY2.X+Quartz 2.0+easyui 1.3.4无缝接入 MVC5+E ...

  7. asp.net mvc5 oracle,ASP.NET MVC5网站开发用户注册(四)

    一.默认Web项目的更改 用户这部分还是自己做,所以删除自动生成的用户相关代码. 二.添加Member区域 在web项目上点右键 添加 区域Member. 添加Home控制器,选择MVC5控制器-空 ...

  8. ASP.NET + MVC5 入门完整教程七 -—-- MVC基本工具(上)

    这里主要介绍三类工具之一的 依赖项注入(DI)容器,其他两类 单元测试框架和模仿工具以后介绍. 1.准备示例项目 从创建一个简单的示例开始,名称为"EssentialTools" ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统

    ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...) 开发工具:VS2015(2012以上)+SQL2008R2以上数据库  您可以有偿获取一份最新源码联 ...

最新文章

  1. 查阅arXiv论文新神器,一行代码比较版本差别,Github新开源!
  2. 官方全面解读“5G+工业互联网”
  3. 在Microsoft Teams中的Visio协作
  4. 前端开发小工具SuperApp——Ctrl+S自动刷新浏览器
  5. JSP手机商城系统设计网站
  6. where 1=1会影响索引吗_MySQL之InnoDB存储引擎:索引的使用
  7. 结对第一次—原型设计
  8. 《Kotlin项目实战开发》第1章 Kotlin是什么 1
  9. js基础-10-url,src,href的理解
  10. 网络安全--文件分离工具 foremost
  11. 吉珠计算机专业插本学校,2015年吉珠与北理珠的专插本考生必看:招生专业数据统计...
  12. 中国资源卫星应用中心免费卫星遥感数据介绍
  13. python的基础使用之字典(涅槃之路8)
  14. COMSOL泰森多边形Voronoi图多孔骨架优化模型受力分析
  15. python文本匹配_python 匹配@
  16. 《Linux操作系统 - RK3288开发笔记》第2章 G-3288-02开发环境搭建
  17. 举安全之盾,防事故之患
  18. [5GC] [图解5GC信令流程] PDU会话建立
  19. GD32学习2——流水灯
  20. 华为EC6108V9A_RK3128_安卓4.4.4_卡刷固件包-内有教程-当贝纯净桌面

热门文章

  1. java试讲题目,常见的Java面试题汇总
  2. 电脑生成siri语音_Siri for Mac:苹果电脑也有语音助手
  3. mysql 常用数据库连接池_常见的数据库连接池
  4. java 序列化保存_保存到二进制/序列化Java
  5. c语言每条代码的含义,为我解释一下,代码的意思。谢谢了。
  6. 安装oracle 10g闪退,Windows 7安装Oracle 10g常见错误及解决方法
  7. 课题开题报告范文样本_成都汽车职业技术学校举行 2020年省、市、区课题开题报告会...
  8. 校友会2019中国大学计算机,校友会2019中国计算机类一流专业排名,清华大学排名第一...
  9. 案例:用一条 SQL 语句查询出每门课都大于 80 分的学生姓名
  10. 基于Vitual Box建立虚拟机,虚拟机系统为Linux Ubuntu16.04