ASP.NET MVC教程五:ASP.NET MVC中的路由

一、概述

在ASP.NET MVC架构中,控制器在3大核心构件中处于中心地位,通过控制器支配模型和视图,然而从浏览器发出的请求到控制器还需要路由的协助,路由将特定的请求和控制器的动作对应起来。

在ASP.NET MVC程序中,路由主要有两方面的职责:

  1. 与入站的请求相匹配,将这些请求映射到控制器的动作中。
  2. 构造出站的URL,这些URL可以响应控制器的动作。

二、路由原理

1、注册路由

先看Global.asax中的代码:

网站启动的时候执行Application_Start方法,通过RouteConfig.RegisterRoutes(RouteTable.Routes)这段代码进行路由的注册,在RegisterRoutes上面F12转到定义,可以查看该方法,其实就是App_Start文件夹下面的RouteConfig类,该类定义如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;namespace ASPNETMVCDemo
{/// <summary>/// RouteCollection 所有路由的集合/// </summary>public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){// 表示忽略路由   只要URL满足这个正则规则,就不使用路由// .axd 是因为iis6给没有后缀的请求加个asd,然后支持MVC的请求routes.IgnoreRoute("{resource}.axd/{*pathInfo}");// 默认路由规则// 里面使用的是命名参数,顺序可以改变
            routes.MapRoute(// 路由名称   RouteCollection是个字典 每个路由都要有自己的名称,相同名称的路由会被覆盖name: "Default",// url的正则规则,去掉域名和端口后的地址进行匹配url: "{controller}/{action}/{id}",// 默认值defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}
}

注册路由其实就是把路由规则添加到RouteCollection路由集合中。

解释说明:

  1. RegisterRoutes方法是在应用程序启动时(Application_Start)被调用执行的。
  2. RegisterRoutes方法的作用:注册路由。它的参数是一个集合对象,这个集合对象就是用来保存多项路由数据的。一项路由数据实际上就是某种形式的URL路径和控制器及其Action的关系,根据这个关系,MVC才能执行到控制器。
  3. 那么怎么添加这种路由数据呢?即调用RegisterRoutes方法里面的routes.MapRoute方法。该方法的第一个参数是路由的名称,类似于Dictionary字典里面的key。第二个参数表示的是URL或者是地址。第三个参数是一个匿名类型,表示该路由相关的默认数据,可以看作一个字典。
  4. 我们注意到第二个参数其实就是占位符表示的URL,这个占位符是用大括号和里面的字符串表示的。可以看出里面不是某种硬编码的URL地址(这里的controller代表所有的控制器,而不是某一个具体的控制器。同理,action也是代表所有的方法,而不是某一个具体的action方法),这样就增加了灵活性,就是用“/”把URL分成三部分。还有我们注意到占位符表示的URL是没有域名的,这个是允许的,这种匹配是不考虑域名的。
  5. 在ASP.NET MVC中我们见得最多的是“{controller}/{action}/{id}”这种形式的URL,那么controller和action这两个单词是否有特殊的用途呢,能不能改变这两个单词的写法。答案是不能的。这时因为会把controller、action和id当做字典或集合的key值来存储对应的URL片段,这样框架在处理时,会读取键名为controller的数据,比如Home,然后得到要执行的控制器是HomeController。同样会从字典中读取键名为action的数据,比如Index,然后得到要执行的Action方法是Index。如果这两个单词写错了,就执行不到相应的controller和action方法了。所以一定要记住写成controller和action是一种约定,其他参数的定义就没有这种要求了。但是action和controller的位置可以修改。

启动程序,这时URL地址是:http://localhost:49730

其实该地址相当于在浏览器里面输入:http://localhost:49730/Home/Index,这时因为在路由规则里面设置了默认值,如果没有控制器和action方法,则默认是Home控制器下面的Index方法。

修改URL里面的controller和action,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;namespace ASPNETMVCDemo
{/// <summary>/// RouteCollection 所有路由的集合/// </summary>public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){// 表示忽略路由   只要URL满足这个正则规则,就不使用路由// .axd 是因为iis6给没有后缀的请求加个asd,然后支持MVC的请求routes.IgnoreRoute("{resource}.axd/{*pathInfo}");// 默认路由规则// 里面使用的是命名参数,顺序可以改变
            routes.MapRoute(// 路由名称   RouteCollection是个字典 每个路由都要有自己的名称,相同名称的路由会被覆盖name: "Default",// url的正则规则,去掉域名和端口后的地址进行匹配url: "{controller1}/{action1}/{id}",// 默认值defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}
}

 然后运行程序查看结果:

这时程序运行出错,所以说controller和action千万不能写错。把controller和action改回正确的,然后颠倒controller和action的位置,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;namespace ASPNETMVCDemo
{/// <summary>/// RouteCollection 所有路由的集合/// </summary>public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){// 表示忽略路由   只要URL满足这个正则规则,就不使用路由// .axd 是因为iis6给没有后缀的请求加个asd,然后支持MVC的请求routes.IgnoreRoute("{resource}.axd/{*pathInfo}");// 默认路由规则// 里面使用的是命名参数,顺序可以改变
            routes.MapRoute(// 路由名称   RouteCollection是个字典 每个路由都要有自己的名称,相同名称的路由会被覆盖name: "Default",// url的正则规则,去掉域名和端口后的地址进行匹配url: "{action}/{controller}/{id}",// 默认值defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}
}

 在运行程序查看结果:

这说明:controller和action的位置是可以颠倒的。这时如果想输入完整的URL地址就行访问就应该输入:http://localhost:49730/Index/Home。

2、路由匹配

2.1、匹配方式一

看下面的截图:

解释说明:

  1. {parameter}:花括弧加任意长度的字符串表示模糊匹配,字符串不能定义成controller和action。默认路由规则就是使用模糊匹配,没有指明具体是哪个控制器里面的哪个action方法。
  2. 字面量即一个常数字符串,这个字符串可以在大括弧与大括弧之间,也可以在最前面或最后面。
  3. 两个大括弧之间没有任何的字面量是不可以的。

 看下面的示例:

首先修改Home控制器里面的Index方法,修改后的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;namespace ASPNETMVCRoute.Controllers
{public class HomeController : Controller{public ActionResult Index(){string paras = "";// 遍历获取参数值foreach(KeyValuePair<string,object> keyValue in RouteData.Values){paras += string.Format($"{keyValue.Key}={keyValue.Value}  ");}// 通过ViewData向页面传值ViewData["msg"] = paras;return View();}public ActionResult About(){ViewBag.Message = "Your application description page.";return View();}public ActionResult Contact(){ViewBag.Message = "Your contact page.";return View();}}
}

 修改对应的视图,在界面展示ViewData["msg"]的值:

@{ViewBag.Title = "Home Page";
}<div class="jumbotron"><h1>ASP.NET</h1><p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p><p><a href="https://asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</a></p><!--展示ViewData["msg"]的值--><p style="color:red;">@ViewData["msg"]</p></div><div class="row"><div class="col-md-4"><h2>Getting started</h2><p>ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites thatenables a clean separation of concerns and gives you full control over markupfor enjoyable, agile development.</p><p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301865">Learn more &raquo;</a></p></div><div class="col-md-4"><h2>Get more libraries</h2><p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p><p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301866">Learn more &raquo;</a></p></div><div class="col-md-4"><h2>Web Hosting</h2><p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p><p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301867">Learn more &raquo;</a></p></div>
</div>

 1、使用{parameter}做模糊匹配其实就是默认路由规则:

routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

 运行程序查看结果:

2、使用字面量做精确匹配

路由规则如下代码所示:

routes.MapRoute(name: "const",url: "admin/{controller}/{action}"
);

 运行程序,在浏览器里面输入:http://localhost:64957/admin/home/index,运行结果如下:

3、不允许连续的URL参数

路由规则如下:

routes.MapRoute(name: "blx",// 错误的URL// url: "{language}{country}/{controller}/{action}"url: "{language}-{country}/{controller}/{action}"
);

运行程序,URL里面输入:http://localhost:64957/chinese-china/home/index,运行结果如下:

2.2、匹配方式二

看下面截图:

解释说明:

  1. 使用“*”来匹配URL剩余的部分,如*plus放在一个表达式的尾部,最后尾部的URL会保存为plus为键名的字典值。

看下面的路由规则:

routes.MapRoute(name: "RouteRule",url: "{controller}/{action}/{query-name}/{*plus}"
);

 运行程序,在URL里面输入:http://localhost:64957/home/index/123/wqer_1234,运行结果如下:

2.3、匹配方式三

看下面截图:

解释说明:

  1. 在URL表达式中有一种特殊的情况,就是URL表达式可能和实际的URL有多种匹配情况,这时候遵守贪婪匹配的原则(即从后往前进行匹配)。

路由规则1:

routes.MapRoute(name: "tlppone",url: "{controller}/{action}/{filename}.{ext}"
);

 运行程序,在URL里面输入:http://localhost:64957/home/index/2342.234.234.aspx,运行结果如下:

路由规则2:

routes.MapRoute(name: "tlpptwo",url: "{controller}/{action}/{foo}xyz{bar}"
);

 运行程序,在URL里面输入:http://localhost:64957/home/index/xyzxyzxyzwer23,运行结果如下:

完整路由规则代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;namespace ASPNETMVCRoute
{public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");// 使用字面量做精确匹配// http://localhost:64957/admin/home/index
            routes.MapRoute(name: "const",url: "admin/{controller}/{action}");// 不允许连续的URL参数// http://localhost:64957/chinese-china/home/index
            routes.MapRoute(name: "blx",// 错误的URL// url: "{language}{country}/{controller}/{action}"url: "{language}-{country}/{controller}/{action}");// 使用*号匹配URL剩余部分// http://localhost:64957/home/index/2342.234.234.aspx 与第一个和第二个路由规则都匹配,显示第一个,说明路由匹配的顺序是从上往下// http://localhost:64957/home/index/123/wqer_1234
            routes.MapRoute(name: "RouteRule",url: "{controller}/{action}/{query-name}/{*plus}");// 贪婪匹配// http://localhost:64957/home/index/2342.234.234.aspx
            routes.MapRoute(name: "tlppone",url: "{controller}/{action}/{filename}.{ext}");// 贪婪匹配2// http://localhost:64957/home/index/xyzxyzxyzwer23
            routes.MapRoute(name: "tlpptwo",url: "{controller}/{action}/{foo}xyz{bar}");routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}
}

3、URL参数默认值

3.1、参数默认值一

看下面的截图:

解释说明:

  1. 如上图所示,我们使用了参数的默认值,上图下方的URL都是匹配这个路由的,如果没有使用默认值,那么就只能使用http://localhost/home/index/1这种完整形式的URL地址了。

路由规则代码如下:

// 参数默认值一
routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

3.2、参数默认值二

看下面截图:

解释说明:

  1. 首先我们说的路由项只提供部分URL片段默认值的情况,一条规则就是如果在路由项中使用默认值,但是没有提供全部默认值,那么没有提供默认值的必须通过URL提供。在上面截图中,控制器必须在URL里面提供。

路由规则如下:

// 参数默认值二:默认值不提供的必须通过URL提供
routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { action = "Index", id = UrlParameter.Optional });

 这时直接运行程序,因为没有提供controller,所以程序会报错:

然后在URL里面输入:http://localhost:55650/Home,就可以正常访问了:

3.4、参数默认值三

解释说明:

  1. 如果只提供了部分参数,而且提供的部分参数是URL表达式中间的,如上图所示,这种情况下action是不起作用的,所以,这种定义默认值的方式是没有意义的!

路由规则如下:

// 参数默认值三:只提供中间参数的默认值是不起作用的
routes.MapRoute(name: "Default2",url: "{controller}/{action}/{id}",defaults: new { action = "Index" }
);

 

这时候需要在浏览器里面输入完整的URL才能访问。

3.4、参数默认值四

看下面截图:

解释说明:

  1. 最后一种默认值的特殊情况,就是在URL表达式中使用字面量,注意这个字面量是除-之外的任意字符的组合,那么字面量相邻的URL参数的默认值是不起作用的。
  2. 规律:使用/把URL划分成若干个部分,如果各个部分包含了URL参数和字面量,那么给这些URL参数提供默认值是不起作用的。如图所示,给参数2和参数3是不起作用的!

路由规则如下:

// 参数默认值四:只提供中间参数的默认值是不起作用的
routes.MapRoute(name: "Default2",url: "{controller}-{action}",defaults: new { action = "Index" });

运行程序,如果浏览器里面只输入http://localhost:55650/home- 是报错的:

这时需要输入完整的URL地址:http://localhost:55650/home-index

4、参数值约束

 假如我们想对URL后面的数字进行限制,比如四位数字或者两位数字,如下图所示,该如何限制呢?

1、使用正则表达式

如下图所示:

解释说明:

  1. 在MVC的路由中我们可以对URL的各个参数定义约束,有两种约束方法,第一种是使用正则表达式,如上图所示。
  2. MapRoute提供了一个重载方法,就是在默认值后面增加了一个约束的参数,这个参数可以使用匿名类型设置值,在匿名类里面可以设置各种参数对应的正则表达式,如上图所示。

路由规则如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;namespace MVCURLParaConstraint
{public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");// 1、使用正则表达式设置参数值的约束
            routes.MapRoute(name: "Default1",url: "{controller}/{action}/{id}/{year}/{month}/{day}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },// year是4位整数 month和day是2位整数constraints:new { year = @"\d{4}",month=@"\d{2}",day=@"\d{2}"});// 默认路由
            routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}
}

 运行程序,在浏览器里面输入:http://localhost:51244/Home/Index/1/2019/05/24,效果如下:

因为设置了约束month是2位整数,这时将month改为1位整数,然后输入:http://localhost:51244/Home/Index/1/2019/5/24,效果如下:

这时程序就报错了,说明设置的正则约束起作用了。

2、使用约束类

如下图所示:

解释说明:

  1. 在有些时候,如果约束规则很复杂或者正则表达式很难写,或者你根本就不擅长写正则表达式,那么可以考虑第二种约束方式:约束类。
  2. 如上图所示:定义约束类就是要实现IRouteConstraint接口的Match方法,这个方法就是用来判断接口是否匹配的。使用这个约束类的方法也很简单,就是在以前使用正则表达式的地方,换成用约束类的实例赋值,如上图所示。

 路由规则如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;namespace MVCURLParaConstraint
{public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");// 2、使用约束类来约束参数值
            routes.MapRoute(name: "Default1",url: "{controller}/{action}/{id}/{year}/{month}/{day}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },// 使用约束类的实例constraints: new { year = @"\d{4}", month =new MonthConstraint(), day = @"\d{2}" });// 1、使用正则表达式设置参数值的约束//routes.MapRoute(//  name: "Default1",//  url: "{controller}/{action}/{id}/{year}/{month}/{day}",//  defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },//  // year是4位整数 month和day是2位整数//  constraints:new { year = @"\d{4}",month=@"\d{2}",day=@"\d{2}"}// );// 默认路由
            routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}/// <summary>/// 对月进行约束,实现IRouteConstraint接口/// 对年或者日进行约束同理/// </summary>public class MonthConstraint : IRouteConstraint{// 实现Match方法public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection){//  values["month"]表示根据键名或者值//  长度为2,并且在1到12之间表示匹配通过返回true,否则不通过返回falseif (values["month"].ToString().Length==2 &&Convert.ToInt32(values["month"])>=1 &&Convert.ToInt32(values["month"]) <=12){return true;}else{return false;}}}
}

 运行程序,在浏览器里面输入:http://localhost:51244/Home/Index/2/2019/05/24 ,效果如下:

5、路由匹配顺序

如下图所示:

解释说明:

  1. 如图所示,上面的URL跟哪个路由规则匹配呢?答案是匹配Default1这个路由,为什么会是这样呢?其实如果只注册单独的一条路由,这两条路由规则都是匹配这个URL的,这里有一个原则:如果有多条路由都和这个URL匹配,那么就是排在最前面的优先匹配,排在后面的就不在进行匹配。

6、排除路由

解释说明:

  1. 我们注意到RigisterRoutes方法中默认的第一句代码是routes.IgnoreRoute方法,他的作用就是排除路由,比如上图下面的URL不会在路由表中匹配的,而是直接被忽略掉!

  2. 如果出了.axd以外的文件需要忽略,那么在IgnoreRoute方法里面添加需要忽略的路由即可。

5、由URL到控制器

先看下面的截图:

解释说明:

  1. 通过前面路由注册的代码会最终形成一个路由集合的数据,可以看作是一个路由表(RouteTable),那么请求是如何通过URL进入到相应的控制器及Action方法的呢?
  2. 如上图所示,请求到达ASP.NET MVC应用程序后,首先会经过一个名为“UrlRoutingModule”的HttpModule,HttpModule可以过滤每一个请求,UrlRoutingModule的作用就是根据请求的URL从路由表中查找和URL匹配的路由,然后从匹配的路由中得到一个名为MvcHandler的HttpHandler,之后就执行它的ProcessRequest方法,在ProcessRequest方法的内部找到Controller,并继续往下执行。
  3. 说到这里可能有疑问:某项路由数据是怎样联系到一个HttpHandler的呢?如下图中的源码所示:MapRoute方法实际上包含这样一段代码,在new的时候会初始化一个MvcRouteHandler对象,然后通过MvcRouteHandler的GetHttpHandler方法可以得到真正的处理程序MvcHandler。

上面说的UrlRoutingModule在哪里呢?看下面截图:

6、从控制器中获取URL值的方式

从控制器中获取URL中的值共有三种方式:

解释说明:

  1. Request.QueryString只能获取以?分隔的参数值!
  2. RouteDate.Values[“id”]就是当前字典上的路由数据,通过访问键名的方式得到键值,比如URL模式匹配的字符串是id,这里必须是id。

  3. Action方法的参数和路由字典的参数是对应的,MVC框架在执行action之前会首先为这些参数赋值。

6.1、Request.QueryString

控制器代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;namespace MVCURlValue.Controllers
{public class HomeController : Controller{/// <summary>///  Request.QueryString/// </summary>/// <returns></returns>public ActionResult Index(){if(Request.QueryString["bookid"]!=null){string value = Request.QueryString["bookid"];ViewData["msg"] = value;}return View();}public ActionResult About(){ViewBag.Message = "Your application description page.";return View();}public ActionResult Contact(){ViewBag.Message = "Your contact page.";return View();}}
}

 

视图也代码如下:

@{ViewBag.Title = "Home Page";
}<div class="jumbotron"><h1>ASP.NET</h1><p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p><p><a href="https://asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</a></p><p style="color:red;font-weight:bold;">@ViewData["msg"]</p>
</div><div class="row"><div class="col-md-4"><h2>Getting started</h2><p>ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites thatenables a clean separation of concerns and gives you full control over markupfor enjoyable, agile development.</p><p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301865">Learn more &raquo;</a></p></div><div class="col-md-4"><h2>Get more libraries</h2><p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p><p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301866">Learn more &raquo;</a></p></div><div class="col-md-4"><h2>Web Hosting</h2><p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p><p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301867">Learn more &raquo;</a></p></div>
</div>

程序运行效果:

6.2、RouteData.Values

控制器代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;namespace MVCURlValue.Controllers
{public class HomeController : Controller{/// <summary>///  Request.QueryString/// </summary>/// <returns></returns>//public ActionResult Index()//{//    if(Request.QueryString["bookid"]!=null)//    {//        string value = Request.QueryString["bookid"];//        ViewData["msg"] = value;//    }//    return View();//}/// <summary>///  RouteData.Values/// </summary>/// <returns></returns>public ActionResult Index(){string value = $"controller={RouteData.Values["controller"]},action={RouteData.Values["action"]}";ViewData["msg"] = value;return View();}public ActionResult About(){ViewBag.Message = "Your application description page.";return View();}public ActionResult Contact(){ViewBag.Message = "Your contact page.";return View();}}
}

运行效果:

这时会遇到一个问题,如果在URL里面还有其他参数呢?比如下面的情况

 

这时候如果要获取id的值就要修改代码,那么有没有其他简便的方式呢?看下面代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;namespace MVCURlValue.Controllers
{public class HomeController : Controller{/// <summary>///  Request.QueryString/// </summary>/// <returns></returns>//public ActionResult Index()//{//    if(Request.QueryString["bookid"]!=null)//    {//        string value = Request.QueryString["bookid"];//        ViewData["msg"] = value;//    }//    return View();//}/// <summary>///  RouteData.Values/// </summary>/// <returns></returns>public ActionResult Index(){// 方式一//string value = $"controller={RouteData.Values["controller"]},action={RouteData.Values["action"]}";// 方式二string value = "";foreach(var item in RouteData.Values){value += $"{item.Key}={item.Value}  ";}ViewData["msg"] = value;return View();}public ActionResult About(){ViewBag.Message = "Your application description page.";return View();}public ActionResult Contact(){ViewBag.Message = "Your contact page.";return View();}}
}

 运行效果:

因为RouteData.Values是一个字典集合,所以可以遍历RouteData.Values,这样无论URL里面有多少参数,都可以获取到对应的value值。

6.3、action参数

控制器代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;namespace MVCURlValue.Controllers
{public class HomeController : Controller{/// <summary>///  Request.QueryString/// </summary>/// <returns></returns>//public ActionResult Index()//{//    if(Request.QueryString["bookid"]!=null)//    {//        string value = Request.QueryString["bookid"];//        ViewData["msg"] = value;//    }//    return View();//}/// <summary>///  RouteData.Values/// </summary>/// <returns></returns>//public ActionResult Index()//{//    // 方式一//    //string value = $"controller={RouteData.Values["controller"]},action={RouteData.Values["action"]}";//    // 方式二//    string value = "";//    foreach(var item in RouteData.Values)//    {//        value += $"{item.Key}={item.Value}  ";//    }//    ViewData["msg"] = value;//    return View();//}/// <summary>///  action参数///  方法参数名称必须和URL里面参数名称保持一致/// </summary>/// <returns></returns>public ActionResult Index(string controller,string action){string value = $"controller={controller},action={action}";ViewData["msg"] = value;return View();}public ActionResult About(){ViewBag.Message = "Your application description page.";return View();}public ActionResult Contact(){ViewBag.Message = "Your contact page.";return View();}}
}

运行效果:

7、由路由到URL

解释说明:

  1. 1.由路由生成URL其实就是简单的两句代码,第一步就是使用RouteCollection对象的GetVirtualPath方法,通过该方法可以返回一个VirtualPahData对象,该类型表示有关路由和虚拟路径的信息,包含了两个重载的方法,区别是第二个方法可以指定路由项的名称,就是添加路由时,设置的路由键名,参数Values表达生成URL时设置的参数值,是一个字典类型。

  2. 1.得到VirtualPahData实例后,就可以通过他的VirtualPath属性值得到URL地址,它是一个字符串类型,从路由的这个功能可以看出,他是有双向功能的,不同于URL重写!

看下面的案例:

修改RouteConfig代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;namespace MVCRouteToUrl
{public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");routes.MapRoute(name: "Default2",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", id = UrlParameter.Optional });// 默认路由匹配规则
            routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}
}

控制器代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;namespace MVCRouteToUrl.Controllers
{public class HomeController : Controller{public ActionResult Index(){// 1.不使用路由名称的方式生成URLVirtualPathData vp= RouteTable.Routes.GetVirtualPath(null, new RouteValueDictionary(new { controller = "Home", action = "Index2", id = 4 }));string url = vp.VirtualPath;ViewData["msg"] = url;return View();}public ActionResult About(){ViewBag.Message = "Your application description page.";return View();}public ActionResult Contact(){ViewBag.Message = "Your contact page.";return View();}}
}

 界面运行效果:

在看下面一种方式:

控制器代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;namespace MVCRouteToUrl.Controllers
{public class HomeController : Controller{public ActionResult Index(){// 1.不使用路由名称的方式生成URL//VirtualPathData vp= RouteTable.Routes.GetVirtualPath(null, new RouteValueDictionary(new { controller = "Home", action = "Index2", id = 4 }));//string url = vp.VirtualPath;//ViewData["msg"] = url;// 2.根据路由名称生成URL// 因为controller和id有默认值,所以这里只指定action的值VirtualPathData vp = RouteTable.Routes.GetVirtualPath(null, "Default2", new RouteValueDictionary(new { action = "Index5" }));string url = vp.VirtualPath;ViewData["msg"] = url;return View();}public ActionResult About(){ViewBag.Message = "Your application description page.";return View();}public ActionResult Contact(){ViewBag.Message = "Your contact page.";return View();}}
}

 运行效果:

 

转载于:https://www.cnblogs.com/dotnet261010/p/10909527.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/482440.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文梳理深度学习算法演进

来源&#xff1a;https://zhuanlan.zhihu.com/p/464515049作者&#xff1a;Peter潘欣编辑&#xff1a;蘑菇先生学习记涉及语音、图像、nlp、强化学习、隐私保护、艺术创作、目标检测、医疗、压缩序列、推荐排序等方向。文章较长&#xff0c;耐心读完会有收获。1. 前言如果说高德…

ASP.NET MVC教程八:_ViewStart.cshtml

一、引言 _ViewStart.cshtml是在ASP.NET MVC 3.0及更高版本以后出现的&#xff0c;用Razor模板引擎新建项目后&#xff0c;Views目录下面会出现一个这样的文件&#xff1a; 打开_ViewStart.cshtml文件&#xff0c;里面只有一行代码&#xff1a; 这行代码表示使用Views文件夹下的…

2021年全球十大工程成就,中国有几个? | 科技袁人

来源&#xff1a; 风云之声视频链接&#xff1a;西瓜视频&#xff1a;https://www.ixigua.com/7068180516549329415本视频发布于2021年2月25日&#xff0c;观看量已达7.4万次精彩呈现&#xff1a;2021年&#xff0c;中国工程院院刊《Engineering》组织了一个“全球十大工程成就…

formSelects-v4.js 基于Layui的多选解决方案

详情链接地址&#xff1a; https://hnzzmsf.github.io/example/example_v4.html#select_search_server1、闲谈杂趣v3传送门 v3文档其实思考了很久, 还是放弃了v3, 因为开发v3的时候很粗暴, 按照编程角度来看就是硬撸, 也怪自己实力有限, 所以反思了一下, 尝试着继续前行...…

将公平注入AI:机器学习模型即使在不公平数据上训练也能产生公平输出

来源&#xff1a;ScienceAI编译&#xff1a;绿萝如果使用不平衡的数据集训练机器学习模型&#xff0c;比如一个包含远多于肤色较浅的人的图像的数据集&#xff0c;则当模型部署在现实世界中时&#xff0c;该模型的预测存在严重风险。但这只是问题的一部分。麻省理工学院的研究人…

使用ngModel创建组件

angular/forms里有个接口用来实现支持[(ngModel)]&#xff0c;具体可查ControlValueAccessor&#xff0c;这边还未深入理解只是为了开发组件而初步了解 interface ControlValueAccessor {writeValue(obj: any): voidregisterOnChange(fn: any): voidregisterOnTouched(fn: any)…

制定城市大脑建设标准应遵循的十条原则探讨

作者&#xff1a;刘锋本文发表于2022年3月《中国建设信息化杂志》2015以来&#xff0c;城市大脑被提出并成为前沿科技和智慧城市建设领域的新热点。到2022年&#xff0c;全国已经有包括北京、上海、杭州、深圳、郑州、呼和浩特、合肥等数百个城市宣布建设城市大脑的规划。有包括…

图灵测试,时至今日还有意义吗?

来源&#xff1a;学术头条我们必须承认&#xff0c;机器运行时的很多中间状态&#xff0c;是在设计初始指令时无法预见的。机器自己也会感悟出很多知识。在这种情況下&#xff0c;我们有必要将机器视为智能的。艾伦图灵图灵测试由人工智能之父—艾伦图灵提出&#xff0c;指测试…

AI科普微视频丨深度学习如何帮助自动驾驶

来源&#xff1a;中国人工智能学会人工智能是如何产生的&#xff1f;人工智能的发展为什么充满曲折&#xff1f;为什么说图灵是人工智能之父&#xff1f;为加大AI科普力度&#xff0c;推动文化传播&#xff0c;中国人工智能学会推出了“AI科普微视频”栏目&#xff0c;以每期2~…

在新的数学证明中,人工智能取胜

来源&#xff1a;ScienceAI编辑&#xff1a;绿萝一个以 AlphaGo 等人工智能系统为原型的新计算机程序解决了组合学和图论中的几个未解决问题。去年 3 月&#xff0c;爱荷华州立大学&#xff08;Iowa State University&#xff09;的数学家 Leslie Hogben 和 Carolyn Reinhart 收…

day44-前端知识之HTML内容

什么是前端?什么是后端? # 任何与用户直接打交道的操作界面都可以称之为前端,前端跟python没有任何关系 比如:电脑界面,手机界面,平板界面# 暂时先理解成 幕后操作者(不直接与用户打交道)为什么要学前端? 因为全栈开发工程师就是同时懂前端和后端 1.信心满满 老子一定能学会…

车路协同让城市更智慧

来源&#xff1a;深城物联在高速发展的现代社会&#xff0c;纷繁复杂的城市道路交织成奔腾不息的交通动脉。今年&#xff0c;全国政协委员、百度董事长兼首席执行官李彦宏在提案中关注“智能交通”“自动驾驶”。在新一代信息技术不断发展的背景下&#xff0c;汽车与城市道路的…

gin-jwt对API进行权限控制

前言 之前文章简单介绍了如何运行ginvue的前后端分离开源项目&#xff0c;该项目是学习了Gin实践教程后结合vue-element-admin写的&#xff0c;该教程讲得很详细&#xff0c;适合入门Gin。本篇文章将介绍ginvue的前后端分离开源项目中如何使用gin-jwt对API进行权限验证。 安装g…

Michael Brostein 最新几何深度学习综述:超越 WL 和原始消息传递的 GNN

来源&#xff1a;前沿科技编译&#xff1a;OGAI编辑&#xff1a;陈彩娴如何突破基于 WL 测试和消息传递机制的 GNN 的性能瓶颈&#xff1f;且看几何深度学习旗手、牛津大学教授 Michael Brostein 如是说。图可以方便地抽象关系和交互的复杂系统。社交网络、高能物理、化学等研究…

day45-前端CSS

1.0 CSS介绍 CSS&#xff08;Cascading Style Sheet&#xff0c;层叠样式表)定义如何显示HTML元素。 当浏览器读到一个样式表&#xff0c;它就会按照这个样式表来对文档进行格式化&#xff08;渲染&#xff09;。 2.0 CSS语法 2.1 CSS实例 每个CSS样式由两个组成部分&#xff1…

人工智能克服了类脑硬件的绊脚石

来源&#xff1a;ScienceAI编辑&#xff1a;萝卜皮当今最成功的人工智能算法——人工神经网络&#xff0c;松散地基于我们大脑中复杂的真实神经网络网络。但与我们高效的大脑不同&#xff0c;在计算机上运行这些算法会消耗巨大的能量&#xff1a;最大的模型在其生命周期中消耗的…

图灵奖起源

来源 &#xff1a; 图灵人工智能在计算机科学的世界里&#xff0c;也有很多带来了全球变革的超级英雄。他们都曾经辉煌一时&#xff0c;但逐渐被公众遗忘。于是我们想做一件事情&#xff0c;用直观的动漫方式&#xff0c;带大家认识计算机宇宙中的那些超级英雄。故事&#xff0…

吵翻了!AI 顶会设置媒体静默期,作者不信邪提前宣传被拒稿,加强盲审是促进公平还是阻止了学术交流?...

来源&#xff1a;AEIC学术交流中心3月2日&#xff0c;计算机视觉三大顶会之一的CVPR2022论文接收结果公布&#xff0c;在经历了漫长的社交媒体静默期后&#xff0c;社交媒体被论文作者刷屏了&#xff0c;部分作者还展示了自己的论文成果。1CVPR2022论文接收结果作为人工智能领域…

巨头们的先进封装技术解读

来源 &#xff1a; 图灵人工智能在上《先进封装最强科普》中&#xff0c;我们对市场上的先进封装需求进行了一些讨论。但其实具体到各个厂商&#xff0c;无论是英特尔&#xff08;EMIB、Foveros、Foveros Omni、Foveros Direct&#xff09;、台积电&#xff08;InFO-OS、InFO-L…

猜测未来微服务架构

微服务架构 微服务的概念在2014年3月由Martin Fowler首次提出。 微服务架构解决的核心问题及其相应的开源组件如下所示&#xff1a; RPC框架 (Service-to-service calls) Spring Boot/Spring MVCDubbogRPCthrift服务注册和发现 (Service registration and discovery) 注册中心 …