当前位置:首页 > Windows程序 > 正文

设置WebApi里面命名空间参数

2021-05-25 Windows程序

在这种情况下:

技术分享

如果没有特别处理,会报:

技术分享

所以要像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; } } }

对它进行了一点点的修改,

旧版本的命名空间选.号的最后一个

我设置的取全名命名空间

#Samples/WebApi/NamespaceControllerSelector/NamespaceHttpControllerSelector.cs

设置WebApi里面命名空间参数

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/71131.html