zoukankan      html  css  js  c++  java
  • AreaHttpControllerSelector 对 Web Api 实现 Area 路由控制

    结合此文章:http://www.cnblogs.com/wuhuacong/p/5828038.html

    using System;
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Net.Http;
    using System.Reflection;
    using System.Web.Http;
    using System.Web.Http.Controllers;
    using System.Web.Http.Dispatcher;
    using System.Web.Http.Routing;
    
    namespace PEMSoft.Web.AppServer
    {
        /// <summary>
        /// Area路由控制,如URL中含{action}则通过Area查找控制器,不存在{area}或找不到控制器则按默认规则再找一次
        /// 作者:ifu25
        /// 日期:2017/07/08
        /// 参考:http://www.jianshu.com/p/8242215cd8c0 、 http://www.cnblogs.com/Silicon-Fado/p/3571938.html
        /// </summary>
        public class AreaHttpControllerSelector : DefaultHttpControllerSelector
        {
            #region 变量
    
            /// <summary>
            /// Area名称
            /// </summary>
            private const string _areaRouteVariableName = "area";
    
            private readonly HttpConfiguration _configuration;
    
            private Dictionary<string, Type> _apiControllerTypes;
    
            /// <summary>
            /// 所有API控制器集合
            /// </summary>
            private Dictionary<string, Type> ApiControllerTypes
            {
                get { return _apiControllerTypes ?? (_apiControllerTypes = GetControllerTypes()); }
            }
    
            #endregion
    
            /// <summary>
            /// 构造
            /// </summary>
            public AreaHttpControllerSelector(HttpConfiguration configuration) : base(configuration)
            {
                _configuration = configuration;
            }
    
            /// <summary>
            /// 覆写父类的选择控制器方法,通过此方法实现根据Area查找控制器
            /// </summary>
            public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
            {
                //选通过Area查找控制器,找不到则忽略Area再找一次
                return GetApiController(request) ?? base.SelectController(request);
            }
    
            #region 内部方法
    
            /// <summary>
            /// 获取所有控制器
            /// </summary>
            private static Dictionary<string, Type> GetControllerTypes()
            {
                var assemblies = AppDomain.CurrentDomain.GetAssemblies();
    
                var types = assemblies.SelectMany(a => a.GetTypes().Where(t => !t.IsAbstract && t.Name.EndsWith(ControllerSuffix) && typeof(IHttpController).IsAssignableFrom(t)))
                    .ToDictionary(t => t.FullName, t => t);
    
                return types;
            }
    
            /// <summary>
            /// 为给定的HttpRequestMessage选择带Area的控制器,没有Area则返回null
            /// </summary>
            private HttpControllerDescriptor GetApiController(HttpRequestMessage request)
            {
                var controllerName = base.GetControllerName(request);
    
                var areaName = GetAreaName(request);
                if (string.IsNullOrEmpty(areaName))
                {
                    return null;
                }
    
                var type = GetControllerTypeByArea(areaName, controllerName);
                if (type == null)
                {
                    return null;
                }
    
                return new HttpControllerDescriptor(_configuration, controllerName, type);
            }
    
            /// <summary>
            /// 从HttpRequestMessage获取Area,没有指定Area则返回null
            /// </summary>
            private static string GetAreaName(HttpRequestMessage request)
            {
                var data = request.GetRouteData();
    
                if (!data.Values.ContainsKey(_areaRouteVariableName))
                {
                    return null;
                }
    
                return data.Values[_areaRouteVariableName].ToString().ToLower();
            }
    
            /// <summary>
            /// 获取指定Area下的控制器
            /// </summary>
            /// <param name="areaName">Area名称</param>
            /// <param name="controllerName">控制器名称</param>
            private Type GetControllerTypeByArea(string areaName, string controllerName)
            {
                var areaNameToFind = string.Format(".{0}.", areaName.ToLower());
                var controllerNameToFind = string.Format(".{0}{1}", controllerName, ControllerSuffix);
    
                return ApiControllerTypes.Where(t => t.Key.ToLower().Contains(areaNameToFind) && t.Key.EndsWith(controllerNameToFind, StringComparison.OrdinalIgnoreCase))
                        .Select(t => t.Value).FirstOrDefault();
            }
    
            #endregion
        }
    }
    
  • 相关阅读:
    WP7 可以在XAML中使用的 缓存图片控件(适合静态)
    wp7蛋疼的90M内存限制,优化图片使用内存(4)[解决]
    Caliburn.Micro for wp7 学习笔记(2) : 响应 Butto事件
    Caliburn.Micro for wp7 学习笔记(3) : 响应 Butto事件原理
    Caliburn.Micro for wp7 学习笔记(1) : 建立 Caliburn.Micro 框架的 wp7 项目
    anthem.net 简单学习
    新公司研发能力低下,何去何从?
    C/C++指针和取地址操作
    利用bochs 调试(转)
    winform模式对话框和非模式对话框
  • 原文地址:https://www.cnblogs.com/vcoo/p/9860225.html
Copyright © 2011-2022 走看看