结合此文章: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
}
}

AreaHttpControllerSelector 对 Web Api 实现 Area 路由控制的更多相关文章

  1. 【ASP.NET Web API教程】4.1 ASP.NET Web API中的路由

    原文:[ASP.NET Web API教程]4.1 ASP.NET Web API中的路由 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容. ...

  2. Web Api源码(路由注册)

    这篇文章只是我学习Web API框架的输出,学习方法还是输出倒逼输入比较行得通,所以不管写的好不好,坚持下去,肯定有收获.篇幅比较长,仔细思考阅读下来大约需要几分钟. 做.NET开发有好几年时间了,从 ...

  3. Web API中的路由(一)——约定路由

    一.Web API中的路由概念 路由的作用用一句话说明:通过request的uri找到处理该请求的Controller,Action,以及给Action的参数赋值. 一些路由的基本概念: route: ...

  4. ASP.NET Web API中的路由

    ASP.NET Web API的默认路由在App_Start目录中的WebApiConfig.cs文件中定义的. public static class WebApiConfig { public s ...

  5. Web API中的路由(二)——属性路由

    一.属性路由的概念 路由让webapi将一个uri匹配到对应的action,Web API 2支持一种新类型的路由:属性路由.顾名思义,属性路由使用属性来定义路由.通过属性路由,我们可以更好地控制We ...

  6. Web API配置自定义路由

    默认访问Web API时,是无需指定method名.它会按照默认的路由来访问.如果你的Web API中出现有方法重载时,也许得配置自定义路由: 标记1为自定义路由,标记2为默认路由,需要把自定义路由排 ...

  7. ASP.NET WEB API 中的路由调试与执行过程跟踪

    路由调试 RouteDebugger 是调试 ASP.NET MVC 路由的一个好的工具,在ASP.NET WEB API中相应的有 WebApiRouteDebugger ,Nuget安装 Inst ...

  8. WebApi官网学习记录---web api中的路由

    如果一条路由匹配,WebAPI选择controller和action通过如下方式: 1.找到controller,将"controller"赋值给{controller}变量 2. ...

  9. Web API框架学习——路由(一)

    HttpConfiguration(ASP.NET Web API管道的配置是通过HttpConfiguration来完成) : 包括路由注册在内的对整个ASP.NET Web API管道的配置是通过 ...

随机推荐

  1. java通过IP地址获取物理位置

    import java.io.*; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern ...

  2. Linux学习笔记:Jenkins的使用

    在windows中使用Jenkins(Linux系统下类似),步骤是: 1 从官网下载jenkins项目的war包 2 将jenkins.war放到tomcat的webapps目录中,启动tomcat ...

  3. 【转】 vxWorks下常用的几种延时方法

    在应用编程的时候,通常会碰到需要一个任务在特定的延时之后执行一个指定的动作,如等待外设以确保数据可靠,控制扬声器发声时间以及串口通信超时重发等.这就需要利用定时器机制来计量特定长度的时间段. vxWo ...

  4. unity技巧

    在之前的程序编写过程中,虽然对相关的方法进行了实例化,但是在运行的时候总是会出现“未将对象引用设置到对象的实例”,出现该种问题的原因是由于在实例化后,没有对实例化进行引用赋值,所以导致相关变量无法在其 ...

  5. centos7 hbase 搭建笔记

    1.require:java环境,本地可用的hadoop 2.拷贝hbase文件(hive-1.2.6) 3.设置环境变量 export HBASE_HOME=/data/spark/bin/hbas ...

  6. FMS4.5( Adobe Flash Media Server4.5)流媒体服务器搭建

    下载FMS4.5 下载地址:http://pan.baidu.com/s/1pJLi5Ur(已更新) FMS是用于用户之间相互通讯的新平台.它集成了Flash多媒体交互的特性,又添加了实时音频和实时数 ...

  7. 牛客训练四:Applese 走方格(细节)

    题目链接:传送门 思路:主要是n=1,m=2或者n=2,m=1时,不是-1. #include<iostream> #include<cstdio> #include<c ...

  8. js, javascript 图片懒加载 实例代码

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 理解shell的eval命令

    看以下两条命令:[zhangsan@XEN /sys]$ a="ls";b="\$a";c="$b";"$c"Hey! ...

  10. (最长不降子序列)最少拦截系统 -- hdu -- 1257

    http://acm.hdu.edu.cn/showproblem.php?pid=1257 最少拦截系统 Time Limit: 2000/1000 MS (Java/Others)    Memo ...