• WebApi自定义返回类型和命名空间实现


    1.自定义ContentNegotiator

    /// <summary>
        /// 返回json的ContentNegotiator
        /// </summary>
        public class JsonContentNegotiator : IContentNegotiator
        {
            private readonly JsonMediaTypeFormatter _jsonFormatter;
    
            public JsonContentNegotiator(JsonMediaTypeFormatter formatter)
            {
                _jsonFormatter = formatter;
            }
    
            public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
            {
                return new ContentNegotiationResult(_jsonFormatter, new MediaTypeHeaderValue("application/json"));
            }
        }

    2.自定义HttpControllerSelector

    /// <summary>
        /// 设置api支持namespace
        /// </summary>
        public class NamespaceHttpControllerSelector : DefaultHttpControllerSelector
        {
            private const string NamespaceRouteVariableName = "namespace_name";
            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 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 keys
                           where k.EndsWith(string.Format(".{0}{1}", controllerName,
                           DefaultHttpControllerSelector.ControllerSuffix), StringComparison.CurrentCultureIgnoreCase)
                           select k;
                }
    
                string[] namespaces = (string[])namespaceName;
                return from n in namespaces
                       join 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("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.Count() == 0)
                {
                    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 })));
            }
        }
    

     3.注册路由

    public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                //注册返回json的ContentNegotiator,替换默认的DefaultContentNegotiator
                var jsonFormatter = new JsonMediaTypeFormatter();
                config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));
    
                //注册支持namespace的HttpControllerSelector,替换默认DefaultHttpControllerSelector
                config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration));
    
                config.Routes.MapHttpRoute(
                    name: "PC",
                    routeTemplate: "api/pc/{controller}/{action}/{id}",
                    defaults: new
                    {
                        id = RouteParameter.Optional,
                        namespace_name = new string[] { "HGL.Web.ApiControllers.PC" }
                    }
                );
    
                config.Routes.MapHttpRoute(
                    name: "Phone",
                    routeTemplate: "api/phone/{controller}/{action}/{id}",
                    defaults: new
                    {
                        id = RouteParameter.Optional,
                        namespace_name = new string[] { "HGL.Web.ApiControllers.Phone" }
                    }
                );
    
                config.Routes.MapHttpRoute(
                    name: "ApiDefault",
                    routeTemplate: "api/{controller}/{action}/{id}",
                    defaults: new
                    {
                        id = RouteParameter.Optional,
                        namespace_name = new string[] { "HGL.Web.ApiControllers" }
                    }
                );
            }
        }
    
  • 相关阅读:
    Go源码文件与命令
    K8s控制器
    odoo 在form视图sheet右上角增加按钮
    odoo 常用widget
    odoo tree视图中实现横向滚动条
    可能是智障的高二生活
    千题计划
    闲谈
    线性代数与simplex
    好题集锦
  • 原文地址:https://www.cnblogs.com/xishuqingchun/p/4135313.html
Copyright © 2020-2023  润新知