设置WebApi里面命名空间参数
在这种情况下:
如果没有特别处理,会报:
所以要像MVC中的控制器一下配置一个命名空间参数,webapi里面没有自带这个功能
代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web.Http; using System.Web.Http.Dispatcher; using AutoData.Utility; namespace AutoData { public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); //config.HostNameComparisonMode = HostNameComparisonMode.Exact; config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "Admin Area Default", routeTemplate: "api/admin/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional, namespaceName = "AutoData.Areas.Admin.Controllers" } ); config.Routes.MapHttpRoute( name: "IndustryInsight Area Default", routeTemplate: "Api/IndustryInsight/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "ComputeFormula Area Default", routeTemplate: "Api/ComputeFormula/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional , namespaceName = "AutoData.Areas.ComputeFormula.Controllers"} ); config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config)); } } }
最后一句设置,也可以配置在全局类里面:
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration));
功能是一样的
NamespaceHttpConrollerSelector类
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net; using System.Net.Http; using System.Text.RegularExpressions; using System.Web; using System.Web.Http; using System.Web.Http.Controllers; using System.Web.Http.Dispatcher; using System.Web.Http.Routing; namespace AutoData.Utility { public class NamespaceHttpControllerSelector : IHttpControllerSelector { private const string NamespaceKey = "namespaceName"; private const string ControllerKey = "controller"; private readonly HttpConfiguration _configuration; private readonly Lazy<Dictionary<string, HttpControllerDescriptor>> _controllers; private readonly HashSet<string> _duplicates; public NamespaceHttpControllerSelector(HttpConfiguration config) { _configuration = config; _duplicates = new HashSet<string>(StringComparer.OrdinalIgnoreCase); _controllers = new Lazy<Dictionary<string, HttpControllerDescriptor>>(InitializeControllerDictionary); } private Dictionary<string, HttpControllerDescriptor> InitializeControllerDictionary() { var dictionary = new Dictionary<string, HttpControllerDescriptor>(StringComparer.OrdinalIgnoreCase); // Create a lookup table where key is "namespace.controller". The value of "namespace" is the last // segment of the full namespace. For example: // MyApplication.Controllers.V1.ProductsController => "V1.Products" IAssembliesResolver assembliesResolver = _configuration.Services.GetAssembliesResolver(); IHttpControllerTypeResolver controllersResolver = _configuration.Services.GetHttpControllerTypeResolver(); ICollection<Type> controllerTypes = controllersResolver.GetControllerTypes(assembliesResolver); foreach (Type t in controllerTypes) { var segments = t.Namespace.Split(Type.Delimiter); // For the dictionary key, strip "Controller" from the end of the type name. // This matches the behavior of DefaultHttpControllerSelector. var controllerName = t.Name.Remove(t.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length); //var key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", segments[segments.Length - 1], controllerName); //旧版本 var key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", t.Namespace.ToString(), controllerName); //新版本 // Check for duplicate keys. if (dictionary.Keys.Contains(key)) { _duplicates.Add(key); } else { dictionary[key] = new HttpControllerDescriptor(_configuration, t.Name, t); } } // Remove any duplicates from the dictionary, because these create ambiguous matches. // For example, "Foo.V1.ProductsController" and "Bar.V1.ProductsController" both map to "v1.products". foreach (string s in _duplicates) { dictionary.Remove(s); } return dictionary; } // Get a value from the route data, if present. private static T GetRouteVariable<T>(IHttpRouteData routeData, string name) { object result = null; if (routeData.Values.TryGetValue(name, out result)) { return (T)result; } return default(T); } public HttpControllerDescriptor SelectController(HttpRequestMessage request) { IHttpRouteData routeData = request.GetRouteData(); if (routeData == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } // Get the namespace and controller variables from the route data. string namespaceName = GetRouteVariable<string>(routeData, NamespaceKey); if (namespaceName == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } string controllerName = GetRouteVariable<string>(routeData, ControllerKey); if (controllerName == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } // Find a matching controller. string key = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", namespaceName, controllerName); HttpControllerDescriptor controllerDescriptor; if (_controllers.Value.TryGetValue(key, out controllerDescriptor)) { return controllerDescriptor; } else if (_duplicates.Contains(key)) { throw new HttpResponseException( request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Multiple controllers were found that match this request.")); } else { throw new HttpResponseException(HttpStatusCode.NotFound); } } public IDictionary<string, HttpControllerDescriptor> GetControllerMapping() { return _controllers.Value; } } }
对它进行了一点点的修改,
旧版本的命名空间选.号的最后一个
我设置的取全名命名空间
这样设置以后会发现一起没有设置命名空间的路由会发生错误,所有WebApiConfig里面的路由必须设置命名空间
http://www.cnblogs.com/nikyxxx/p/3356659.html
http://aspnet.codeplex.com/SourceControl/changeset/view/dd207952fa86#Samples/WebApi/NamespaceControllerSelector/NamespaceHttpControllerSelector.cs
http://www.osdo.net/article/2015/01/13/160.html
http://blog.csdn.net/starfd/article/details/41728655