asp.net MVC5為WebAPI添加命名空間的支持

前言

默認情況下,微軟提供的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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540630.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540630.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540630.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[轉載] Python3.X 線程中信號量的使用方法示例

參考鏈接&#xff1a; 示例說明Python2.x和Python3.x之間的重要區別 信號量semaphore 是一個變量&#xff0c;控制著對公共資源或者臨界區的訪問。信號量維護著一個計數器&#xff0c;指定可同時訪問資源或者進入臨界區的線程數。下面這篇文章主要給大家介紹了關于Python3.X 線…

從流程的自動化中獲得最大價值的10種方式

流程自動化很好&#xff0c;如果它可以節省時間并減少錯誤。但是如果它不能在業務流程中“很好地契合”&#xff0c;那么會難以得到普及。問問有誰沒有對語音助手感到傷腦筋。 所幸的是&#xff0c;某些最佳實踐讓你可以從流程自動化中獲得最大價值&#xff0c;以下就是其中的1…

java中null是常量嗎_C_NULL Julia中的常量

java中null是常量嗎Julia| C_NULL常數 (Julia | C_NULL Constant) C_NULL is a constant of Ptr{Nothing} type in Julia programming language, it represents the null pointer value, which is used for C Null Pointer while calling external code. C_NULL是Julia編程語言…

[轉載] Python京東搶購

參考鏈接&#xff1a; 從Python獲取輸入 Python京東搶購 分析其中提交信息接口的參數&#xff0c;可以成功搶購商品&#xff0c;并且可以提交訂單。。。。2018年7月17日 提交信息的獲取 直接提交信息對post提交分析其中的參數。 經過分析參數大多數在&#xff1a;https…

6.04 從字符串中刪除不需要的字符

需求&#xff1a;刪除所有的0和元音字母。 select ename,replace(replace(replace(replace(replace(ename,A,),E,),I,),O,),U,) as stripped1,sal,replace(sal,0,) stripped2from emp;轉載于:https://www.cnblogs.com/liang545621/p/7518766.html

Scala分號

Scala分號 (Scala semicolons) A semicolon or semi-colon (;) is a punctuation mark in programming, it is used to separate multiple lines of code. It is common in major programming languages like C, C, Java, Pascal. In modern programming languages like Python…

[轉載] python通過adb獲取android手機耗電量

參考鏈接&#xff1a; 從Python中控制臺獲取輸入 把開發者模式打開&#xff0c;激活 adb 調試&#xff0c;然后可以使用以下python代碼獲取安卓手機的耗電量 # -*- coding: utf-8 -*- import re import os def getSelectDevice(): pip os.popen(adb devices) result pip.…

ES6之主要知識點(二) 變量的解構賦值。默認值

引自http://es6.ruanyifeng.com/#docs/destructuring 數組解構賦值默認值對象解構賦值用途1.數組的解構賦值 let [a, b, c] [1, 2, 3]; let [foo, [[bar], baz]] [1, [[2], 3]]; foo // 1 bar // 2 baz // 3let [ , , third] ["foo", "bar", "baz&…

python無符號轉有符號_Python | 散布符號

python無符號轉有符號There are multiple types of Scatter Symbols available in the matplotlib package and can be accessed through the command marker. In this article, we will show some examples of different marker types and also present a list containing all…

[轉載] 基于LSTM的股票預測模型_python實現_超詳細

參考鏈接&#xff1a; 從Python獲取輸入 文章目錄 一、背景二、主要技術介紹1、RNN模型2、LSTM模型3、控制門工作原理四、代碼實現五、案例分析六、參數設置七、結論完整程序下載 一、背景 近年來&#xff0c;股票預測還處于一個很熱門的階段&#xff0c;因為股票市場的波動…

shell -eom_EOM的完整形式是什么?

shell -eomEOM&#xff1a;消息結尾 (EOM: End Of Message) EOM is an abbreviation of "End Of Message". EOM是“消息結尾”的縮寫 。 It is an expression, which is commonly used in the Gmail platform. It is also written as Eom or eom. It is written at …

在eclipse中啟動Tomcat訪問localhost:8080失敗項目添加進Tomcat在webapp中找不到

軟件環境&#xff1a;Eclipse oxygen&#xff0c; Tomcat8.5 #在eclipse中啟動Tomcat訪問localhost:8080失敗 在eclipse中配置tomcat后&#xff0c;打開tomcat后訪問localhost:8080后無法出現登陸成功的界面,即無法出現下面的界面 在eclipse中的servers狀態欄中雙擊tomcat&…

[轉載] 【基礎教程】Python input()函數:獲取用戶輸入的字符串

參考鏈接&#xff1a; 從Python中控制臺獲取輸入 input() 是 Python 的內置函數&#xff0c;用于從控制臺讀取用戶輸入的內容。input() 函數總是以字符串的形式來處理用戶輸入的內容&#xff0c;所以用戶輸入的內容可以包含任何字符。 input() 函數的用法為&#xff1a; str…

程序員簡歷工作模式_簡歷的完整形式是什么?

程序員簡歷工作模式簡歷&#xff1a;簡歷 (CV: Curriculum Vitae) The CV is an abbreviation of Curriculum Vitae. It is a written outline summary of a persons educational training and qualifications and his other experiences. It is an absolute profile of a cand…

[轉載] Python新手寫出漂亮的爬蟲代碼1——從html獲取信息

參考鏈接&#xff1a; Python中從用戶獲取多個輸入 Python新手寫出漂亮的爬蟲代碼1 初到大數據學習圈子的同學可能對爬蟲都有所耳聞&#xff0c;會覺得是一個高大上的東西&#xff0c;仿佛九陽神功和乾坤大挪移一樣&#xff0c;和別人說“老子會爬蟲”&#xff0c;就感覺特別…

在Scala中設置&()方法

Scala中的Set&#xff06;()方法 (The Set &() method in Scala) The &() method in the Set is used to create a new set in Scala. This new set created contains all elements from the other two sets that are common for both of the given sets i.e. new set …

[轉載] python與c/c++相比有哪些優勢

參考鏈接&#xff1a; Python輸入和C, Java速度對比 理論上&#xff0c;python的確比C/C慢&#xff08;我對Java的開發沒有經驗&#xff0c;無法評論&#xff09;。這一點不用質疑。 C/C是編繹語言&#xff0c;直接使用的是機器指令&#xff0c;而python總是跑在的虛擬機上&am…

清空日志的三種方法

方法一&#xff1a;echo "" >test.log方法二&#xff1a;> test.log方法三&#xff1a;cat /dev/null >test.log轉載于:https://www.cnblogs.com/liang545621/p/7528509.html

splat net_Ruby中的Splat參數

splat netRuby Splat參數 (Ruby Splat Arguments) We have learnt how to work with methods in Ruby? We are very well aware of the fact that methods may or may not consume any arguments. Let us discuss the methods which consume argument or have a predefined ar…

ajax的訪問 WebService 的方法

轉自原文 ajax的訪問 WebService 的方法 如果想用ajax進行訪問 首先在web.config里進行設置 添加在 <webServices> <protocols> <add name "HttpPost" /> <add name "HttpGet" /> </protocols> </webServices> <s…