ASP.NET Web Api - Route

Web Api 不支持多路由

就是说 如果你创建了 多个 Area

就算在 route 中注册了 {area}  web api 也是不认得

 

所以需要重写规则

public class NamespaceHttpControllerSelector : DefaultHttpControllerSelector
    {
        private const string NamespaceRouteVariableName = "namespaceName";
        private readonly HttpConfiguration _configuration;
        private readonly Lazy<ConcurrentDictionary<string, Type>> _apiControllerCache;

        public NamespaceHttpControllerSelector(HttpConfiguration configuration) : base(configuration)
        {
            _configuration = configuration;
            _apiControllerCache = new Lazy<ConcurrentDictionary<string, Type>>(InitializeApiControllerCache);
        }

        private ConcurrentDictionary<string, Type> InitializeApiControllerCache()
        {
            IAssembliesResolver assembliesResolver = this._configuration.Services.GetAssembliesResolver();
            Dictionary<string, Type> 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;
            IHttpRouteData data = request.GetRouteData();
            IEnumerable<string> keys = _apiControllerCache.Value.ToDictionary(t => t.Key,
                    t => t.Value, StringComparer.CurrentCultureIgnoreCase).Keys.ToList();

            if (!data.Values.TryGetValue(NamespaceRouteVariableName, out namespaceName))
            {
                return from k in keys
                       where k.EndsWith($".{controllerName}{ControllerSuffix}", StringComparison.CurrentCultureIgnoreCase)
                       select k;
            }

            return from n in (string[])namespaceName
                   join k in keys on $"{n}.{controllerName}{ControllerSuffix}".ToLower() equals k.ToLower()
                   select k;
        }

        public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
        {
            Type type;
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            string controllerName = this.GetControllerName(request);
            if (string.IsNullOrEmpty(controllerName))
            {
                throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,
                    string.Format("No route providing a controller name was found to match request URI '{0}'",
                    new object[] { request.RequestUri })));
            }
            IEnumerable<string> fullNames = GetControllerFullName(request, controllerName);
            if (!fullNames.Any())
            {
                throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,
                        string.Format("No route providing a controller name was found to match request 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("No route providing a controller name was found to match request URI '{0}'",
                new object[] { request.RequestUri })));
        }
    }
View Code
public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config));

            config.Routes.MapHttpRoute(
                "AdminApi",
                "api/Admin/{controller}/{action}/{id}",
                new { action = "Index", id = RouteParameter.Optional, namespaceName = new[] { "RouteDemo.Areas.Admin.Controllers" } }
            );

            config.Routes.MapHttpRoute(
                "SiteApi",
                "api/Site/{controller}/{action}/{id}",
                new { action = "Index", id = RouteParameter.Optional, namespaceName = new[] { "RouteDemo.Areas.Site.Controllers" } }
            );

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{area}/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
View Code

 

posted @ 2017-10-09 16:20  `Laimic  阅读(237)  评论(0)    收藏  举报