ASP.NETMVC教程五:ASP.NETMVC中的路由⼀、概述
在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⾥⾯的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 }
);
}
}
}
在运⾏程序查看结果:
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="asp" class="btn btn-primary btn-lg">Learn more »</a></p>
<!--展⽰ViewData["msg"]的值-->
<p >@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 that
enables a clean separation of concerns and gives you full control over markup
for enjoyable, agile development.
</p>
<p><a class="btn btn-default" href="go.microsoft/fwlink/?LinkId=301865">Learn more »</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="go.microsoft/fwlink/?LinkId=301866">Learn more »</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="go.microsoft/fwlink/?LinkId=301867">Learn more »</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}"
);
3、不允许连续的URL参数
路由规则如下:
routes.MapRoute(
name: "blx",
// 错误的URL
// url: "{language}{country}/{controller}/{action}"
url: "{language}-{country}/{controller}/{action}"
);
2.2、匹配⽅式⼆
看下⾯截图:
解释说明:
1. 使⽤“*”来匹配URL剩余的部分,如*plus放在⼀个表达式的尾部,最后尾部的URL会保存为plus为键名的字典值。
看下⾯的路由规则:
routes.MapRoute(
name: "RouteRule",
url: "{controller}/{action}/{query-name}/{*plus}"
);
2.3、匹配⽅式三
看下⾯截图:
解释说明:
1. 在URL表达式中有⼀种特殊的情况,就是URL表达式可能和实际的URL有多种匹配情况,这时候遵守贪婪匹配的原则(即从后往前进
⾏匹配)。
路由规则1:
routes.MapRoute(
name: "tlppone",
url: "{controller}/{action}/{filename}.{ext}"
);
路由规则2:
routes.MapRoute(
name: "tlpptwo",
url: "{controller}/{action}/{foo}xyz{bar}"
);
完整路由规则代码如下:
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}");
/
/ 使⽤字⾯量做精确匹配
//localhost:64957/admin/home/index
routes.MapRoute(
name: "const",
url: "admin/{controller}/{action}"
);
// 不允许连续的URL参数
//localhost:64957/chinese-china/home/index
routes.MapRoute(
name: "blx",
// 错误的URL
/
/ url: "{language}{country}/{controller}/{action}"
url: "{language}-{country}/{controller}/{action}"
);
// 使⽤*号匹配URL剩余部分
//localhost:64957/home/index/2342.234.234.aspx 与第⼀个和第⼆个路由规则都匹配,显⽰第⼀个,说明路由匹配的顺序是从上往下            //localhost:64957/home/index/123/wqer_1234
routes.MapRoute(
name: "RouteRule",
url: "{controller}/{action}/{query-name}/{*plus}"
);
// 贪婪匹配
//localhost:64957/home/index/2342.234.234.aspx
routes.MapRoute(
name: "tlppone",
url: "{controller}/{action}/{filename}.{ext}"
);
// 贪婪匹配2
//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参数默认值
aspnet和net的区别3.1、参数默认值⼀
看下⾯的截图:
解释说明:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。