这里我们就分享一些MVC框架原理上的东西,就从URL,路由机制等开始吧!关于MVC简单的介绍大家可以去下载我分享的视频或者自己去搜一些资料了解下,这就关于MVC基本介绍就不在罗嗦了!直接开始我们的URL路由部分。
简介路由体系
MVC路由主要有两个功能:
1. 检查传入的URL找出的对应的控制器(Controller)和方法(Action)请求。这就是MVC的路由体系处理我们客户端请求的目的。
2. URL生成输出。这些URL中出现的HTML渲染特定操作时将调用用户单击链接(此时,它已成为一个再次传入的URL)。
我们开始创建一个项目("Routing"),用的是MVC应用程序是Internet Application模版。因为玩路由这些东东都在Global.asax文件里,所以在VS里打开该文件夹。默认的Global.asax文件如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace Routing { // 注意: 有关启用 IIS6 或 IIS7 经典模式的说明, // 请访问 http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); } public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // 路由名称 "{controller}/{action}/{id}", // 带有参数的 URL new { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值 ); } protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } } }
Application_Start方法由底层的Asp.Net当应用程序的平台第一次启动时,使用RegisterRoutes方法注册路由。该方法的参数是静态RouteTable的属性。这是RouteCollection类的一个实例。接下来我们删除掉RegisterRoutes方法下的内容,因为我们要了解到他(URL模式)到底是怎么一回事,所以我们需要退一步,干掉这些默认(VS)自动创建的路由机制,用我们自己的配置来解开URL模式的真实面目。
简介URL模式
路由系统的工作原理它的魔力,使用了一套路由。这些路由,集体撰写的URL计划方案的应用程序,这是您的应用程序会识别和URL集回应。我们不需要手动输入所有单独的URL。相反,每个路由包含一个URL模式,这是比较传入的URL。如果模式匹配的URL,那么它是用来处理URL路由系统(机制)。譬如在之前的项目实战里,我们可以看到如下的URL:
Http://mysite.com/Admin/Index
这是我们用来访问管理员的产品目录的URL。URL可以分解成几部分。这些URL的组成部分,不包括主机名和查询字符串,被/字符。URL的例子中,有两个部分,如下图1.
图1.第一部分包含Admin,第二部分包含Index。在我们眼里很明显第一部分涉及到的控制器(Controller)和第二部分涉及的动作或者说方法(Action)。当然,我们需要这种关系来表达的方式,路由系统可以明白了,那到底URL模式是不是如下所:
{controller}/{action}
处理传入的URL时,路由系统的工作是相匹配的URL模式,然后从URL中提取值段模式。段使用大括号({***}字符)表示变量。例如模式有两个分部变量名controller(控制器)和 Action(方法)。
我们说匹配模式,MVC应用程序,因为通常都会有多条路由航线,路由机制会比较传入的URL的各条路线的URL模式,直到它可以找到一个匹配。
默认情况下,一个URL模式将匹配任何URL正确数目的片段。对于示例,该示例将匹配任何模式的URL,有两个部分,如下表所示
请求的URL | 细分变量 |
Http://mysite.com/Admin/Index |
controller = Admin action =Index |
Http://mysite.com/Index/Admin |
controller = Index action =Admin |
Http://mysite.com/Apples/Oranges |
controller = Apples action = Oranges |
Http://mysite.com/Admin | 会报错(段过少) |
Http://mysite.com/Admin/Index/Soccer | 会报错(段过多) |
URL模式两个突出的关键行为:
- URL模式是保守的,将匹配有相同的URL模式段的数量。
- URL模式是自由的。如果一个URL确实有正确的段数, 模式将提取的值段变量,不管怎样。
这是默认的行为,这是了解URL模式运作的关键。
正如我们提到的,路由系统不知道任何关于MVC应用程序,这样的匹配URL模式,即使是没有控制器或动作对应的值提取从URL。你可以看到在表中的第二个例子证明了这一点。我们已调换在URL中的Admin和Index段,所以也一直从URL中提取的值调换。
创建和注册一个简单的路由
若你有了一个URL模式的思想,你可以使用它来定义一个路线。打开我们的Global.asax文件,注册一个简单的路由,具体如下:
public static void RegisterRoutes(RouteCollection routes) { Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); routes.Add("MyRoute", myRoute); }
这种方法是稍微更紧凑,主要是因为我们不需要创建一个实例MvcRouteHandler类。 MapRoutem方法是专为使用MVC应用程序。 ASP.NET网页窗体应用程序可以使用的MapPageRoute方法在RouteCollection类定义。运行我们的程序,结果如下图2.
图2.
我们的URL模式已处理的URL,并提取控制器(Controller)变量的值和Action(方法)变量指数。 MVC框架要求的指标方法对我们来说,这是我们选择了互联网应用的MVC项目时创建的主控制器模板。
定义默认值
我们得到一个错误时,我们要求应用程序是默认URL的,它匹配我们定义不确定的路线相。默认URL表示为〜/路由系统,所以有没有可以匹配的控制器和方法变量的分部。我们刚才解释的URL模式是保守的,他们将配合的网址指定号码段。我们也说,这是默认行为。改变这种情况的方法之一行为是使用默认值。默认值是当URL不包含段可以匹配的值。提供一个默认的路由具体代码如下:
public static void RegisterRoutes(RouteCollection routes) { //Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); //routes.Add("MyRoute", myRoute); //提供默认路由 routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" }); }
作为一个匿名类型的属性提供默认值。我们提供了一个指数的行动变量的默认值。这条航线将匹配所有两部分的网址,现在,我们提供了默认值的动作段,路线也将匹配单段以及网址。处理URL时,路由系统将提取的控制器值从单一的URL部分,并用行动变量的默认值。这样,我们可以要求的网址http://mydomain.com/Home和调用索引操作方法在主控制器的。运行结果如下图3.
图3.我们可以进一步定义不包含在所有的任何部分变量的URL,依托在刚刚 默认值来确定的行动和控制器。我们可以使用默认值的默认URL映射,具体代码如下:
public static void RegisterRoutes(RouteCollection routes) { //Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); //routes.Add("MyRoute", myRoute); ////提供默认路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" }); //提供方法和控制器默认值的路由 routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" }); }
通过定义提供方法和控制器的默认值的路由,我们可以直接访问http://mysite即可,运行效果如下图4.
图4.提供控制器和操作变量的默认值,我们已经创造了一个路线将匹配具有变量段为零的地址,一个变量端或两个变量段的部分,具体如下表:
段数 | 例子 | 映射 |
0 | mydomain.com |
controller = Home action = Index |
1 | mydomain.com/Customer |
controller = Customer action = Index |
2 | mydomain.com/Customer/List |
controller = Customer action = Index |
3 | mydomain.com/Customer/List/All | (会报错)段数过多 |
使用静态URL段
并非所有URL模式的细分需要变量。你还可以创建模式静态段。假设我们要匹配这样的网址,支持前缀为公共的URL:
http://mydomain.com/Public/Home/Index
我们配置这样一条模式,具体代码如下:
public static void RegisterRoutes(RouteCollection routes) { //Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); //routes.Add("MyRoute", myRoute); ////提供默认路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" }); //提供方法和控制器默认值的路由 routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" }); //配置静态段的URL模式 routes.MapRoute("", "Public/{controller}/{action}", new { controller = "Home", action = "Index" }); }
这将匹配URL模式包含三个部分,第一,必须是客户的唯一地址。其他两部分可以包含任何值,将用于控制器和行动变量。然后运行访问我们Http://mysite/public/Home/Index,运行结果如下图5.
图5.
我们还可以创建URL模式,有段包含静态和可变因素,具体代码如下:
public static void RegisterRoutes(RouteCollection routes) { //Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); //routes.Add("MyRoute", myRoute); ////提供默认路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" }); //提供方法和控制器默认值的路由 routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" }); //配置静态段的URL模式 routes.MapRoute("", "Public/{controller}/{action}", new { controller = "Home", action = "Index" }); //配置混合段的URL模式 routes.MapRoute("", "X{controller}/{action}"); }
在这条路线的模式匹配任何两个分部的网址,其中第一部分开始字母X为控制器的开始,方法从第二部分。我们可以常识访问下面的URL将匹配路由:
http://mydomain.com/XHome/Index ,运行结果如下图6.
图6.该URL将被定Home控制器上向到Action操作方法。
我们可以结合静态URL段和默认值创建一个特定的URL别名。如果你已经公开发表您的URL模式,并形成了一个与用户的合同可能是有用的。如果重构在这种情况下的应用程序,你需要保留以前的URL格式。打个比方吧!假如我们以前有一个Shop控制器,现在被Home控制器取代了我们如何才能创建一个路由维护旧的URL架构。我们可以用下面的办法,具体代码如下:
public static void RegisterRoutes(RouteCollection routes) { //Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); //routes.Add("MyRoute", myRoute); ////提供默认路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" }); //混合静态URL段和默认值 routes.MapRoute("ShopSchema", "Shop/{action}", new { controller = "Home" }); //配置混合段的URL模式 routes.MapRoute("", "X{controller}/{action}"); //提供方法和控制器默认值的路由 routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" }); //配置静态段的URL模式 routes.MapRoute("", "Public/{controller}/{action}", new { controller = "Home", action = "Index" }); }
我们已经添加的路由匹配任何两部分第一部分是Shop的URL。动作(Action)从第二个URL段值。 URL模式不包含的变量段控制器,所以我们提供的默认值使用。这意味着,(Action)动作上的要求被替代的控制器和现在控制器转换。我们可以更近一步,创建动作(Action)方法重构也不再是在目前的别名控制器。要做到这一点,我们只需创建一个静态的URL,并提供控制器和行动值默认值,具体代码如下:
public static void RegisterRoutes(RouteCollection routes) { //Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); //routes.Add("MyRoute", myRoute); ////提供默认路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" }); //别名的一个控制器和一个方法 routes.MapRoute("ShopSchema2", "Shop/OldAction", new { controller = "Home", action = "Index" }); //混合静态URL段和默认值 routes.MapRoute("ShopSchema", "Shop/{action}", new { controller = "Home" }); //配置混合段的URL模式 routes.MapRoute("", "X{controller}/{action}"); //提供方法和控制器默认值的路由 routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" }); //配置静态段的URL模式 routes.MapRoute("", "Public/{controller}/{action}", new { controller = "Home", action = "Index" }); }
通知,我们首先应以我们新的路由。这是因为具体路由的遵循。如果Shop/ OldAction的要求下进行处理定义路由,例如,我们会得到一个不同的结果和我们想要的结果。该请求将被处理使用404 - Not Found错误页面,而不是为了维护我们与用户之间合约。
细分变量机制
我们不局限于只是控制器和行动变量。我们还可以定义自己的变量,具体代码如下:
public static void RegisterRoutes(RouteCollection routes) { //Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); //routes.Add("MyRoute", myRoute); ////提供默认路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" }); //别名的一个控制器和一个方法 routes.MapRoute("ShopSchema2", "Shop/OldAction", new { controller = "Home", action = "Index" }); //混合静态URL段和默认值 routes.MapRoute("ShopSchema", "Shop/{action}", new { controller = "Home" }); //配置混合段的URL模式 routes.MapRoute("", "X{controller}/{action}"); ////提供方法和控制器默认值的路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" }); //配置静态段的URL模式 routes.MapRoute("", "Public/{controller}/{action}", new { controller = "Home", action = "Index" }); //额外的变量定义URL模式 routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = "DefaultId" }); }
路由的URL模式定义典型的控制器和(Action)动作变量,以及自定义变量名为id。这条路由将匹配任何零到三段的URL。第三内容段将被分配到id变量,如果没有第三部分,则默认值将是使用。我们可以使用RouteData.Values访问任何分部变量在操作方法属性。为了证明这一点,我们添加了一个方法在HomeController,在主控制器类叫做CustomVariable,具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Routing.Controllers { public class HomeController : Controller { public ActionResult Index() { ViewBag.Message = "欢迎使用 ASP.NET MVC!"; return View(); } public ViewResult CustomVariable() { this.ViewBag.CustomVariable = RouteData.Values["id"]; return this.View(); } public ActionResult About() { return View(); } } }
我们添加相应的视图,具体代码如下:
@{ ViewBag.Title = "CustomVariable"; } <h2>Variable: @ViewBag.CustomVariable</h2>
如果您运行的应用程序浏览URL/Home/ CustomVariable/Hello,CustomVariable的在HomeController的方法被称为动作方法,自定义部分变量的值被检索从ViewBag和显示出来,结果如下图7.
图7.
使用自定义变量作为参数的操作方法
使用RouteData.Values属性,只有一个办法来访问自定义路由变量。另一种方法是更优雅。如果我们定义的参数名称与我们的操作方法相匹配的网址模式变量,MVC框架将通过从URL作为参数的操作方法获得的值。例如,自定义变量,在我们上面的路由被称为ID。我们可以修改的CustomVariable的操作方法,因此,它有一个匹配的参数,具体代码如下:
//映射一个自定义URL段变量来一个动作方法参数 public ViewResult CustomVariable(string id ) { this.ViewBag.CustomVariable = this.Index(); return this.View(); }
当路由系统匹配对我们在我们配置的路由表定义的URL网址,价值在URL中的第三部分是分配给自定义变量的指数。 MVC框架的比较段与操作方法的参数列表变量列表,如果匹配的名字,通过从URL值的方法。我们已经定义了id参数为一个字符串,但MVC框架将尝试转换网址值到任何参数类型定义。如果我们宣布id参数为一个int或一个DateTime,然后,我们将收到从解析托安该类型的实例的URL值。这是一个优雅有用的功能,不再需要我们自己处理的转换。
定义可选的URL片段
一个可选的URL部分是一个用户不需要指定,但其中没有默认值是规定。我们指定段的变量是可选的设置默认值UrlParameter.Optional,具体代码如下:
public static void RegisterRoutes(RouteCollection routes) { //Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); //routes.Add("MyRoute", myRoute); ////提供默认路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" }); //别名的一个控制器和一个方法 routes.MapRoute("ShopSchema2", "Shop/OldAction", new { controller = "Home", action = "Index" }); //混合静态URL段和默认值 routes.MapRoute("ShopSchema", "Shop/{action}", new { controller = "Home" }); //配置混合段的URL模式 routes.MapRoute("", "X{controller}/{action}"); ////提供方法和控制器默认值的路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" }); //配置静态段的URL模式 routes.MapRoute("", "Public/{controller}/{action}", new { controller = "Home", action = "Index" }); ////额外的变量定义URL模式 //routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = "DefaultId" }); //指定一个可选的URL片段 routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }); }
这条路由将匹配与否的ID段已提供的网址.下表描述这种路由用于不同的URL。(用一个可选的部分匹配url变量)
段数 | 例子 | 映射 |
0 | mydomain.com | controller= Home action= Index |
1 | mydomain.com/Customer | controller= Customer action= Index |
2 | mydomain.com/Customer/List | controller= Customer action= List |
3 | mydomain.com/Customer/List/All | controller= Customer action= List id = All |
4 | mydomain.com/Customer/List/All/Delete | 会报错(段数过多) |
正如你可以看到其外表,只有当有一个id变量被添加到组变量传入URL中的相应部分。要清楚,这不是id值是空的时,没有提供相应的段;相反,情况是,一个id变量没有被定义。如果你需要知道用户是否提供了有价值的东东,此功能非常有用。如果我们提供了一个id参数的默认值的操作方法,并获得该值,我们将无法告诉如果使用默认值或用户正好请求的URL中的默认值。可选段的一个常见的用途是强制执行的关注点分离,这样的默认值操作方法参数不包含在路由定义。如果你想按照此实践中,你可以使用的C#可选参数功能来定义你的操作方法参数,具体如下:
//定义一个默认值为一个动作方法参数 public ViewResult CustomVariable(string id = "DefaultId") { this.ViewBag.CustomVariable = id; return this.View(); }
运行,结果如下图8.
图8.
定义变长的路由
改变URL模式的默认保守的另一种方法是接受可变数目的URL段。这可以让你任意长度在一个单一的路由,路由网址。您定义的支持做前缀的变量段指定段作为一个包含所有的变量之一,星号(*)。具体实例一个路由如下:
public static void RegisterRoutes(RouteCollection routes) { //Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); //routes.Add("MyRoute", myRoute); ////提供默认路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" }); //别名的一个控制器和一个方法 routes.MapRoute("ShopSchema2", "Shop/OldAction", new { controller = "Home", action = "Index" }); //混合静态URL段和默认值 routes.MapRoute("ShopSchema", "Shop/{action}", new { controller = "Home" }); //配置混合段的URL模式 routes.MapRoute("", "X{controller}/{action}"); ////提供方法和控制器默认值的路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" }); //配置静态段的URL模式 routes.MapRoute("", "Public/{controller}/{action}", new { controller = "Home", action = "Index" }); ////额外的变量定义URL模式 //routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = "DefaultId" }); ////指定一个可选的URL片段 //routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }); //指定一个包括所有变量的路由 routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }); }
我们变成路由,从前面的例子添加一个包括所有的细分变量,这是我们想象的包括所有的变量。现在,这条路由将匹配任何URL。前三段值,分别为控制器,动作和id变量。如果URL中包含额外段,他们都被分配到我们的包括有意变量段(也就是{*catchall})部分。这条路由可以匹配的URL如下表:
段数 | 例子 | 映射 |
0 | mydomain.com | controller= Home action= Index |
1 | mydomain.com/Customer | controller= Customer action= Index |
2 | mydomain.com/Customer/List | controller= Customer action= List |
3 | mydomain.com/Customer/List/All | controller= Customer action= List id = All |
4 | mydomain.com/Customer/List/All/Delete | controller= Customer action= List id = All catchall = Delete |
5 | mydomain.com/Customer/List/All/Delete/Perm | controller= Customer action= List id = All catchall = Delete/Perm |
有段,在这条路线的URL模式匹配的数量没有上限。请注意,段由包扩所有捕获的形式段/段/段。我们是负责处理字符串打破了个别分部。
优先控制器名称空间
当传入的URL匹配的路由,MVC框架的控制器变量的值寻找适当的名称。例如,当控制器变量的值是Home,然后看起来HomeController控制器的MVC框架。这是一个不合格的类名,这意味着,MVC框架并不知道怎么做,如果有两个或两个以上的类称为HomeController在不同的命名空间。当发生这种情况,将报告一个错误,如下图9:
图9.(你可以给项目在加一个HomeController)试试。
这个问题时,往往比较常见,特别是如果你在一个大的MVC工作从其他的开发团队或第三方供应商的控制器使用库的项目。这是自然命名有关用户帐户的AccountController例如,一个控制器,它仅仅是一个时间的问题之前,你遇到命名冲突。为了解决这个问题,我们可以告诉MVC框架,优先某些命名空间当试图解决的一个控制器类的名称,具体代码如下:
public static void RegisterRoutes(RouteCollection routes) { //Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); //routes.Add("MyRoute", myRoute); ////提供默认路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" }); //别名的一个控制器和一个方法 routes.MapRoute("ShopSchema2", "Shop/OldAction", new { controller = "Home", action = "Index" }); //混合静态URL段和默认值 routes.MapRoute("ShopSchema", "Shop/{action}", new { controller = "Home" }); //配置混合段的URL模式 routes.MapRoute("", "X{controller}/{action}"); ////提供方法和控制器默认值的路由 //routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", action = "Index" }); //配置静态段的URL模式 routes.MapRoute("", "Public/{controller}/{action}", new { controller = "Home", action = "Index" }); ////额外的变量定义URL模式 //routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = "DefaultId" }); ////指定一个可选的URL片段 //routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }); ////指定一个包括所有变的路由 //routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }); //指定名称空间解析顺序 routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new[] { "URLsAndRoutes.Controllers" }); }
我们作为一个字符串数组表示的命名空间。在程序运行后,我们已经告诉MVC框架看在URLsAndRoutes.Controllers命名空间之前,寻找到别的地方去。如果有合适的控制器不能被发现在该命名空间,然后将默认的MVC框架到其正常的行为,并看在所有可用的命名空间。名称空间添加到路线都具有同等的优先级。 MVC框架不检查第一个命名空间,然后再移动到第二等等。例如,假设我们添加了两个我们的项目命名空间的路线,代码如下面:
public static void RegisterRoutes(RouteCollection routes)
{
//Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler());
//routes.Add("MyRoute", myRoute);////提供默认路由
//routes.MapRoute("MyRoute", "{controller}/{action}", new { action = "Index" });//别名的一个控制器和一个方法
routes.MapRoute("ShopSchema2", "Shop/OldAction", new { controller = "Home", action = "Index" });//混合静态URL段和默认值
routes.MapRoute("ShopSchema", "Shop/{action}", new { controller = "Home" });//配置混合段的URL模式
routes.MapRoute("", "X{controller}/{action}");////提供方法和控制器默认值的路由
//routes.MapRoute("MyRoute", "{controller}/{action}", new { controller = "Home", act