首先我用MVC4新增一个订单查看的功能

1.创建控制器OrderController

namespace MvcApplication3.Controllers
{
public class OrderController : Controller
{
public ActionResult OrderView()
{
return View();
}
}
}

2.创建视图 OrderView

@{
ViewBag.Title = "OrderView";
} <h2>OrderView</h2>

3.Global配置路由

 public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"OrderView",
"OrderCenter/OrderView.html",
new { controller = "Order", action = "OrderView" },
new string[] { "MvcApplication3" }
); }

我们在做MVC项目时,每次我们新增功能时,都要在golbal文件里注册下该视图的路由,当项目有10个,100个功能,那我们不配置死,而且都在一个文件里global里修改配置,维护起来非常费劲,有没有好的办法来解决这个问题尼,不用再修改global文件,就可自由的配置路由地址

让我们接下来一步步分析

首先我们看MVC路由类RouteCollection的扩展方法 MapRoute 的参数属性

        //
// 摘要:
// Maps the specified URL route and sets default route values and namespaces.
//
// 参数:
// routes:
// A collection of routes for the application.
//
// name:
// The name of the route to map.
//
// url:
// The URL pattern for the route.
//
// defaults:
// An object that contains default route values.
//
// namespaces:
// A set of namespaces for the application.
//
// 返回结果:
// A reference to the mapped route.
//
// 异常:
// System.ArgumentNullException:
// The routes or url parameter is null.
public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, string[] namespaces);

再看下我们在Golbal里调用此方法

routes.MapRoute(
"OrderView", --对应name
"OrderCenter/OrderView.html", --对应url
new { controller = "Order", action = "OrderView" }, --对应object
new string[] { "MvcApplication3" } --对应namespaces
);

看第三个参数 defaults 它包含了路由的Controller名称,Action名称,第四个参数namespaces表示这个Controller所在的命名空间,我们看看我们之前新建的控制器OrderController它的类型是class,而它下面的Action是一个返回类型是ActionResult的方法,再想到命名空间,由此我们是否可以利用反射技术来来循环读取当前应用程序下所有Controller,每个Controller的所有方法Action以及每个Controller所在命名空间

下面我们写下面一段伪代码来分析我们的思路:

  var 控制器类集合=读取当前所有控制器类();
foreach (var 控制器 in 控制器类集合)
{
var action方法数组=获取控制器所有Action方法();
var namespance=获取当前控制器所在命名空间;
var controllerName=获取控制器名称();
foreach(var action in action方法数组)
{
var actionName=获取action名称();
var routerUrl="OrderCenter/OrderView.html";
//注册
routes.MapRoute(
actionName,
routerUrl,
new { controller =controllerName, action = actionName },
new string[] { namespance }
);
}
}

这段伪代码算是解决我们今天讲的主题问题的一部分,为什么尼,因为第二个参数url 我们无法识别或知道每个Controller路由的地址,这样问题还没有解决,我们继续苦逼的维护这我们的golbal路由文件,新增一个功能,来加个配置,如果每个Controller有个属性URL,我们可以设置这个属性,那问题不就解决了嘛,那如何给Controller添加属性尼,这里我们可以利用到C# 特性 Attribute

关于特性MSDN给的定义:

特性提供功能强大的方法,用以将元数据或声明信息与代码(程序集、类型、方法、属性等)相关联。特性与程序实体关联后,即可在运行时使用名为“反射”的技术查询特性。

特性具有以下属性:

  • 特性可向程序中添加元数据。元数据是有关在程序中定义的类型的信息。所有的 .NET 程序集都包含指定的一组元数据,这些元数据描述在程序集中定义的类型和类型成员。可以添加自定义特性,以指定所需的任何附加信息。。

  • 可以将一个或多个特性应用到整个程序集、模块或较小的程序元素(如类和属性)。

  • 特性可以与方法和属性相同的方式接受参数。

  • 程序可以使用反射检查自己的元数据或其他程序内的元数据。有关更多信息。

所以我们定义一个特性类

 [AttributeUsage(AttributeTargets.All, Inherited = true)]
public class RouteAddressAttribute : Attribute
{
public RouteAddressAttribute()
{ }
public RouteAddressAttribute(string name, string address)
{
this.Name = name;
this.Address = address;
}
/// <summary>
/// 地址 【正是我们想要的URL】
/// </summary>
public string Address { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
}

定义了特性类,看我们怎么用它,此时我们再看我的Controller

namespace MvcApplication3.Controllers
{
public class OrderController : Controller
{
[RouteAddress(Name = "订单查看", Address = "OrderCenter/OrderView.html")]
public ActionResult OrderView()
{
return View();
}
}
}

再把我们之前的伪代码编程成真实代码,代码实现如下

namespace MvcApplication3
{
public class RouteMap
{ public static void Redirection(RouteCollection routes, string assemblyName)
{
Assembly assembly = Assembly.Load(assemblyName);
Type[] types = assembly.GetTypes();
List<string> ListAdress = new List<string>();
foreach (Type type in types)
{
#region 读取所有Controller
if (type.Name.Contains("Controller"))
{
string nameSpace = type.Namespace;
string controller = type.Name.Replace("Controller", "");
string action = "";
string address = "";
string routeName = ""; MemberInfo[] memberInfos = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
#region 读取每个Controller的Action
foreach (var item in memberInfos)
{
action = item.Name;
routeName = type.Name + action; var objAttr = item.GetCustomAttributes(typeof(RouteAddressAttribute), false);
if (objAttr != null && objAttr.Length > )
{
#region 获取特性RouteAdress
RouteAddressAttribute temp = (RouteAddressAttribute)objAttr.First();
if (temp != null)
{
address = temp.Address; if (!ListAdress.Contains(address))
{
//实现注册
routes.MapRoute(routeName, address, new { controller = controller, action = action }, new string[] { nameSpace });
ListAdress.Add(address);
}
else
throw new Exception("存在相同路由地址:" + address);
}
#endregion
}
else
{
#region 没加特性的则显示默认地址 Controller/Action
address = string.Format("{0}/{1}", controller, action);
if (!ListAdress.Contains(address))
{
//实现注册
routes.MapRoute(routeName, address, new { controller = controller, action = action }, new string[] { nameSpace });
ListAdress.Add(address);
}
else
throw new Exception("存在相同路由地址:" + address);
#endregion
}
}
#endregion
}
#endregion
}
} }
}

这样Golbal文件里我们添加一行代码就行了。

 public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//调用
RouteMap.Redirection(routes, "MvcApplication3"); }

综上所述,利用特性,利用反射,解决了开发人员繁琐的路由配置工作。

关于特性和反射技术,大家可以看下MSDN,本文不做详细介绍。

自定义MVC路由配置的更多相关文章

  1. MVC 伪静态路由、MVC路由配置,实现伪静态。

    前段时间,研究了一下mvc路由配置伪静态,在网上扒了很多最后还是行不通,所以我现在把这些心得整理出来,供大家分享: 1.mvc中默认路由配置是:http://localhost:24409/Home/ ...

  2. MVC路由配置

    目录 URL Routing 的定义方式 示例准备 给片段变量定义默认值 定义静态片段 自定义片段变量 自定义片段变量的定义和取值 将自定义片段变量作为Action方法的参数 指定自定义片段变量为可选 ...

  3. 理解MVC路由配置(转)

    在上一篇文章中,我简短的谈了一下MVC的底层运行机制,如果对MVC还不是很了解的朋友,可以作为入门的参照.接下来,我开始介绍关于URL路由的相关知识.URL路由不是MVC独有的,相反它是独立于MVC而 ...

  4. mvc 路由配置

    1.URL模式 路由系统用一组路由来实现它的功能,这些路由共同组成了应用系统URL架构或方案,这种URL架构是应用程序能够识别并能对之做出响应的一组URL,当处理一个输入 请求时,路由系统的工作是将这 ...

  5. mvc路由配置.html结尾的伪静态

    mvc 标准的写法 通常是(http://localhost:8149/Home/Index) 路由配置如下: 有时候需求 如 http://localhost:8149/Home/Index 改为h ...

  6. 史上最全的ASP.NET MVC路由配置

    MVC将一个Web应用分解为:Model.View和Controller.ASP.NET MVC框架提供了一个可以代替ASP.NETWebForm的基于MVC设计模式的应用. AD:51CTO 网+ ...

  7. ASP.NET MVC路由配置(转载自http://www.cnblogs.com/zeusro/p/RouteConfig.html )

    把apress.pro.asp.net.mvc.4.framework里的CHAPTER 13翻译过来罢了. XD 首先说URL的构造. 其实这个也谈不上构造,只是语法特性吧. 命名参数规范+匿名对象 ...

  8. ASP.NET MVC路由配置

    一.命名参数规范+匿名对象 routes.MapRoute(name: "Default", url: "{controller}/{action}/{id}" ...

  9. 史上最全的ASP.NET MVC路由配置,以后RouteConfig再弄不懂神仙都难救你啦~

    继续延续坑爹标题系列.其实只是把apress.pro.asp.net.mvc.4.framework里的CHAPTER 13翻译过来罢了,当做自己总结吧.内容看看就好,排版就不要吐槽了,反正我知道你也 ...

随机推荐

  1. css实现响应式全屏背景

    利用css中 background-size:cover  填充整个viewport 注意: 一张背景图像素5000px*5000px在pc端 缩放都基本满足要求 不会出现模糊失真: 但是在移动端使用 ...

  2. ios 界面间跳转方法总结

    接触ios也有一段时间了,偶然间,我们公司的技术总监兼我的导师,问我,你可知道,界面间的跳转有几种方式?我说出了两种,但是也有点含糊其辞,于是我就想一定要找个时间总结一下.有句话说的好,“前人种树,后 ...

  3. Gmail账户安全冰山一角

    本文没有任何价值,只是一个事实的记录. 看到qq邮箱有个代理其他邮箱的功能,就好奇地输入了我的Gmail邮箱,结果代理不成功. 本来没care,后来gmail自己弹出来一封邮件. 后来我确认是本人所为 ...

  4. [转]使用Oracle SQL Developer连接数据库并创建用户

    本文转自:http://blog.csdn.net/xw13106209/article/details/6594738 1.使用sys账户创建数据库连接 安装Oracle 11g会自带一个叫做SQL ...

  5. PV信号量的一些理解

    进程通常分为就绪.运行和阻塞三个工作状态.三种状态在某些条件下可以转换,三者之间的转换关系如下:   进程三个状态之间的转换就是靠PV操作来控制的.PV操作主要就是P操作.V操作和信号量.其中信号量起 ...

  6. Oracle性能调优(AWR)

    一.AWR报告 AWR 是通过对比两次快照(snapshot)收集到的统计信息,来生成报表数据,生成的报表包括多个部分,这点与Statspack生成的报告非常类似.不过AWR在生成报告时,可以选择生成 ...

  7. 【转】Android自动化测试之MonkeyRunner录制和回放脚本(四)

    测试脚本录制: 方案一: 我们先看看以下monkeyrecoder.py脚本: #Usage: monkeyrunner recorder.py #recorder.py  http://mirror ...

  8. 揭开CSS3媒体查询迷雾(min-width和max-width)

    本文参考MichelleKlann的Media Queries Demystified: Min-Width and Max-Width 媒体查询(media queries)是响应式设计(Respo ...

  9. Dremel made simple with Parquet

    http://lastorder.me/tag/parquet.html https://blog.twitter.com/2013/dremel-made-simple-with-parquet 对 ...

  10. Mongodb集群节点故障恢复场景分析

    http://blog.csdn.net/zhangzhaokun/article/details/6299527 一个适当配置的Mongodb分片集群是没有单点故障. 本文描述了分片集群中存在的几种 ...