前一段时间接触了MVC的Area可以将模型、控制器和视图分成各个独立的节点。分区之后,区域路由注册的需求就出来了。

默认的

在MVC项目上右键添加区域之后,在文件夹下会自动添加一个FolderNameAreaRegistration.cs的文件。

public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
} public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}

在其中,定义了一个继承AreaRegistration的类,类下面 重写了AreaName和RegisterArea。当然,这一串代码已经可以很好的解决区域的路由注册问题了。

但是对于这重复的代码有点排斥,另一个也想看看有没有其他的替换方式。

想看看能不能在路由注册那里统一管理

插曲一

之前在开始接触分区的时候,碰到过区域下页面的layout链接错误的问题,后来的解决方式是在ActionLink的routeValue参数里面定义area=""。

情况和这里的有点像,不同的是,上面的需要清除area,这里需要添加area。

插曲二

最近在看《asp.net mvc4高级编程》这本书,接触到一个很有用的工具RouteDebugger。

过程一

路由注册那里,调用的是routes.MapRoute函数,来向RouteTable.Routes中添加route。这个函数有好几个扩展,结合上面插曲一的思路,在扩展函数的defaults里面,尝试添加属性area="Test":

routes.MapRoute(
name: "Test_Default",
url: "Test/{controller}/{action}/{id}",
defaults: new { area = "Test", controller = "AAA", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "MVCTest.Areas.Test.Controllers" });

调试通过RouteDebugger看:

输入/Test/AAA/Index,页面报错,此路不通。

过程二

同事研究这块时,发现除了默认AreaRegistration类以外的方法:

[RouteArea("Admin")]
[RoutePrefix("Test")]
[Route("{action=index}")]
public partial class TestController : Controller
{
}

在区域下的Controller上面添加Route相关特性。主要就三个:Route、RouteArea和RoutePrefix。第一个定义Area,第二个定义Controller,第三个定义默认action值为index。实际调试后,发现前台准确的匹配到了路由,思路OK

到此,结合RouteDebugger,再调试到前台,我们可以看到:

从这个图可以看出,MapRoute的数据定义了Url、Defaults和Constraints,后面的DataTokens不能通过MapRoute函数里面传入。

查看源代码:

public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
{
if (routes == null)
{
throw new ArgumentNullException("routes");
}
if (url == null)
{
throw new ArgumentNullException("url");
} Route route = new Route(url, new MvcRouteHandler())
{
Defaults = CreateRouteValueDictionaryUncached(defaults),
Constraints = CreateRouteValueDictionaryUncached(constraints),
DataTokens = new RouteValueDictionary()
}; ConstraintValidation.Validate(route);
if ((namespaces != null) && (namespaces.Length > ))
{
route.DataTokens[RouteDataTokenKeys.Namespaces] = namespaces;
}
routes.Add(name, route);
return route;
}

注意,上面的DataTokens是new了一个RouteValueDictionary对象。

而想要注入的area数据正是在DataTokens里面。所以上面的第一次尝试失败,是因为数据注入到了Defaults里面。

到了这里,怎么在RegisterRoutes里面统一管理区域的路由注册,思路已经呼之欲出了。

解决方案:

routes.Add(new Route("PaperMaster/{controller}/{action}/{id}"
, new RouteValueDictionary(new { controller = "Papers", action = "Index", id = UrlParameter.Optional })
, new RouteValueDictionary()
, new RouteValueDictionary(new { area = "PaperMaster", namespaces = "Packmage.Web.Areas.PaperMaster.Controllers" })
, new MvcRouteHandler()));

直接实例化Route对象,输入它的各个需要的属性;不用MapRoute,改用Add,直接向RouteTable.Routes中添加route对象。

到此问题解决。留文备用。

PS:以前做winform没有怎么接触.net的源码,现在研究asp.net,开源的模块比较多,越来越多的接触.net的源码,感觉读源码非常重要,也非常有用。能够更加清晰的知道自己的代码在干什么,遇到问题,可以通过查看本质而去寻求直接有效的解决方法,效率也高很多。

Route学习笔记之Area的Route注册的更多相关文章

  1. Asp.net core (学习笔记 路由和语言 route & language)

    https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-2.1 https://doc ...

  2. Route学习笔记

    前言 UrlRoutingModule.class:这块的代码关联了上一篇中路由部分的一个详细说明 一:Route的讲解 1. 路由模板匹配 添加路由: MapRoute 剔除的路由:IgnoreRo ...

  3. HTML&CSS基础学习笔记1.22-简单的注册页面

    一个简单的注册页面 表单提交是前后端数据交互的一种方式. 代码区是一个注册页面,其中包含了以下标签:<form>.<table>.<input>.<butto ...

  4. 微服务学习笔记二:Eureka服务注册发现

    Eureka服务注册发现 服务发现:云端负载均衡,一个基于 REST 的服务,用于定位服务,以实现云端的负载均衡和中间层服务器的故障转移. 1. Service Discovery: Eureka S ...

  5. 高德地图的JSAPI学习笔记【一】

    高德地图的项目要做 学习笔记记录下来 一.注册账号并申请Key  二.准备页面写好 1.在页面添加 JS API 的入口脚本标签,并将其中「您申请的key值」替换为您刚刚申请的 key: <sc ...

  6. linux学习笔记31--命令route和routetrace

    Linux系统的route命令用于显示和操作IP路由表(show / manipulate the IP routing table).要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或 ...

  7. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  8. Dynamic CRM 2013学习笔记(四)单据编号及插件批量注册工具

    基本上每个实体form上都会有单据编号,而且不同的实体编号要求还不太一样,这时就需要一个通用的单据编号插件,可配置以应对不同的需求. 下面简单介绍下实现步骤: 1. 创建二个实体,以保存各实体所要求的 ...

  9. OD调试学习笔记7—去除未注册版软件的使用次数限制

    OD调试学习笔记7—去除未注册版软件的使用次数限制 本节使用的软件链接 (想自己试验下的可以下载) 一:破解的思路 仔细观察一个程序,我们会发现,无论在怎么加密,无论加密哪里,这个程序加密的目的就是需 ...

随机推荐

  1. springmvc 自定义注解

    1. 自定义一个注解 @Documented //文档生成时,该注解将被包含在javadoc中,可去掉 @Target(ElementType.METHOD)//目标是方法 @Retention(Re ...

  2. Android 获取闹钟引发的血案

    想做一个锁屏的软件.锁屏后可以显示闹钟信息. 一开始的思路是通过android content provider获取 mActivityObject.getContentResolver().quer ...

  3. mac 利用 sshpass 自动登录

    mac 利用 sshpass  + 配置文件 实现自动登录 使用方式 https://github.com/vipzhicheng/go  参见此项目 其实原理也就是 脚本 读取配置文件 匹配 参数或 ...

  4. python appium 封装获取toast方法

    获取toast text封装,传入toast 部分文本,返回全部文本 def get_toast_text(self,text): try: toast_loc = (By.XPATH, " ...

  5. WPF 项目升级错误

    今天将一个 WPF 项目从 .NET 4.0 升级至 .NET 4.6.1 时,出现一个错误: 错误        未知的生成错误"程序集"PresentationFramewor ...

  6. js函数调用二种常用方法的例子

    js中函数调用的两种常用方法. 一个js函数 function test(aa){ window.alert("你输入的是"+aa); } 方法一:直接调用 test(" ...

  7. 关于"996",我想说的 - 人在高潮享受成就,人在低潮享受人生

    996 - 9点上班,21点下班,周六必须上班. 这就是IT界的潜规则,之前晚上陪家人看新闻的时候我就看到一则新闻轻描淡写的说了996制度,我当时就想说点甚么,但是没有,然而就仿佛突然的一下爆发了,我 ...

  8. 【Unity】7.2 鼠标输入

    分类:Unity.C#.VS2015 创建日期:2016-04-21 一.简介 在桌面系统的游戏中,鼠标输入是最基本的输入方式之一.游戏很多操作都需要鼠标来完成,例如武器的瞄准和开火.菜单的单击.物体 ...

  9. MySQL 性能跟踪方法

    https://www.cnblogs.com/zhoujinyi/p/5236705.html https://dev.mysql.com/doc/refman/5.7/en/slow-query- ...

  10. (转)go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin

    转自:http://www.baiyuxiong.com/?p=886 ---------------------------------------------------------------- ...