zoukankan      html  css  js  c++  java
  • WebApi支持命名空间重名问题

    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;
    using System.Web.Http.Controllers;
    using System.Web.Http.Dispatcher;
    using System.Web.Http.Routing;

    namespace ZQNB.Common.Web.Api
    {
    //针对WebApi的扩展
    //目的是为了让WebApi支持命名空间的筛选
    //程序启动时,替换IHttpControllerSelector选择器
    //GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration));

    public static class HttpRouteCollectionEx
    {
    public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, string[] namespaces)
    {
    return routes.MapHttpRoute(name, routeTemplate, defaults, null, null, namespaces);
    }
    public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler, string[] namespaces)
    {
    if (routes == null)
    {
    throw new ArgumentNullException("routes");
    }
    var routeValue = new HttpRouteValueDictionary(new { Namespace = namespaces });//设置路由值
    var route = routes.CreateRoute(routeTemplate, new HttpRouteValueDictionary(defaults), new HttpRouteValueDictionary(constraints), routeValue, handler);
    routes.Add(name, route);
    return route;
    }
    }

    public class NamespaceHttpControllerSelector : DefaultHttpControllerSelector
    {
    private const string NamespaceRouteVariableName = "Namespace";
    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>>(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 apiControllerKeys = Enumerable.Empty<string>();
    string[] namespaces = null;
    var data = request.GetRouteData();
    IEnumerable<string> allApiControllers = _apiControllerCache.Value.ToDictionary(t => t.Key,
    t => t.Value, StringComparer.CurrentCultureIgnoreCase).Keys.ToList();
    namespaces = (string[]) this.GetRouteValue(NamespaceRouteVariableName, data);

    if (namespaces != null && namespaces.Any())
    {
    var area = (string) this.GetRouteValue("area", data);
    if (!string.IsNullOrEmpty(area))
    {
    for (int i = 0; i < namespaces.Length; i++)
    {
    if (namespaces[i].Contains("{area}"))
    {
    namespaces[i] = namespaces[i].Replace("{area}", area);
    }
    }
    }

    return from n in namespaces
    join k in allApiControllers on
    string.Format("{0}.{1}{2}", n, controllerName, DefaultHttpControllerSelector.ControllerSuffix)
    .ToLower() equals k.ToLower()
    select k;
    }
    //get the defined namespace
    return allApiControllers.Where(
    k =>
    k.EndsWith(
    string.Format(".{0}{1}", controllerName, DefaultHttpControllerSelector.ControllerSuffix),
    StringComparison.CurrentCultureIgnoreCase));
    }

    private object GetRouteValue(string key, IHttpRouteData httpRouteData)
    {
    object value;
    if (httpRouteData.Route.DataTokens != null &&
    httpRouteData.Route.DataTokens.TryGetValue(key, out value))
    {
    if (value != null)
    {
    return value;
    }

    }
    if (httpRouteData.Values != null && httpRouteData.Values.TryGetValue(key, out value))
    {
    if (value != null)
    {
    return value;
    }
    }
    return null;
    }

    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("No route providing a controller name was found to match request URI '{0}'", new object[] { request.RequestUri })));
    }
    IEnumerable<string> fullNames = GetControllerFullName(request, controllerName);
    var enumerable = fullNames as string[] ?? fullNames.ToArray();
    if (!enumerable.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(enumerable.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 })));
    }
    }
    }

    最后Global

    //设置我们自己的 ControllerFactory
    ControllerBuilder.Current.SetControllerFactory(new NbDefaultControllerFactory(CoreServiceProvider.Current.GetAllInstances<IControllerProvider>()));
    GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration));

  • 相关阅读:
    freeswitch录音功能
    jdk安装
    maven阿里云镜像
    idea安装
    idea新建maven项目
    tomcat安装
    idea新建maven web项目
    idea新建java项目
    webpack使用
    ACE 安装指南及示例
  • 原文地址:https://www.cnblogs.com/zhtbk/p/4837675.html
Copyright © 2011-2022 走看看