Asp.net MVC routing 路由
Asp.net MVC routing是一个独立于FrameWork的独立组件。
Introduce to Routing :
Routing within the Asp.net MVC framework serves two main purposes:
- It matches incoming requests that would not otherwise match a file on the file system and maps the request to a controller action.
Url会匹配输入的请求但是并不是匹配文件系统上的某一个文件,而是映射到某一个Controller的某一个Action。
2.It constructs outgoing Urls that correspond to controller actions.
它会输出一个Url地址用来符合Controller中的某个Action。
asp.net MVC 路由的唯一限制就是两个连续的参数是不被允许的。例如:
{language}-{country}/{controller}/{action } ,和 {controller}.{action}.{id}都是可以的,但是{controller}{action}/{id}是不允许的。
asp.net MVC 添加路由:routes.MapRoute(“simple”,”{Controller}/{action}/{id}”,new{id=UrlParameter.Optional});
Note that the same thing can also be accomplished by setting the id to be an empty string :{id=””}.This semms a lot more concise(简洁) ,so ahy not user this? What,s the difference
Remember earlier when we mentioned that Url parameter values are parsed out of the URL and put into a dictionary.Well when you user UrlParameter.Optional as a default value and no value is supplied in the Url,routing doesn’t even add an entry to the dictionary.If the default value is set to an empty string,the route value dictionary will contain a value with the key “id” and the value as an empty string.In some cases,this distinction is important.It lets you know the difference between the id not being specified,and it being specified but left empty.
在这里我不想说太多Routing的太多细节,因为博客园中已经有太多的大师已经给出了答案,那么我就说些在Routing中会遇到的问题:
1.
routes.MapPageRoute("Static", "static/url", "~/views/home/index.cshtml");
如果你想在注册Routing的时候把一个url指向一个具体的页面,那么你会把这个路由信息放到路由规则中的第一个。现在我就来说这会遇到什么问题:
如果你想利用这个规则来生成一个Url,那么你可能会用这种方式,
@Html.RouteLink("static", new { controller = "home", action = "index", id = UrlParameter.Optional })
那么这个会生成什么Url呢?/Static/url?controller=home&action=index&id=
这个当然不会是我们希望的结果,那么应该如何来避免产生这种Url呢,答案就是使用路由规则的名称。
Use names for all your routes and always use the route name when generate URLs.使用Route的名称来进行URL的生成,无论任何时候都要这样。
2.Catch All Parameters 捕获所有的参数信息
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(“catchAll”,”query/{query-name}/{*extrastuff} );
//注意最后一个参数中含有一个*号,它才是可以捕获所有参数的关键所在
}
/query/select/a/b/c extrastuff=”a/b/c”
/query/select/a/b/c/ extrastuff=”a/b/c”
/query/select/ extrastuff=”” 此时参数为一个空字符串
3.Multiple URL parameters in a segment
When matcging incoming requests,literals within the route URL are matched exactly.URL parameters are matched greedily.
在匹配进入的请求的时候,那些包含路由URL的文本会精确的匹配,但是路由中的URL参数会进行贪婪的匹配,这才是关键所在。
下面举几个简单的例子来进行描述:
{filename}.{ext} /foo.xml.aspx filename=”foo.xml” ext=”aspx” 注意第一个参数没有在foo停止,而是也匹配了后面的内容
my{title}-{cat} /myhouse-dweing title=”house” ,cat=”dweing”
{foo}xyz{bar} xyzxyzxyzblah foo=”xyzxyz”,bar=”blah” 这些都足以表明参数匹配是贪婪匹配
StopRoutingHandler and IgnoreRoute 有时候我们也不想让某些请求进行Routing处理,例如CSS、js、jpg和其他一些资源文件。
我们可以利用StopRoutingHandler来忽略这些请求
routes.Add(new Route("{resource}.axd", new StopRoutingHandler()));
在定义路由选择的时候添加上忽略的请求,就可以避免这些文件类型的请求经过Routing处理。
还有一种更加简洁的方法就是
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
通过这个方法可以实现对资源文件的避免Routing,内部调用的细节是一样的。只不过这种方式更加的简洁。
上面的图表示的asp.net MVC路由映射的原理图,代表了路由映射的基本步骤。
The High-Level Request Routing Pipeline
The routing pipeline consists of the following high-level steps:
1. The UrlRoutingModule attempts to match the current request with the routes registered in
the RouteTable.
2. If a route matches, the Routing module grabs the IRouteHandler from that route.
3. The Routing module calls GetHandler method of the IRouteHandler, which returns the
IHttpHandler that will be used to process the request.
4. ProcessRequest is called on the HTTP handler, thus handing off the request to be handled.
5. In the case of ASP.NET MVC, the IRouteHandler is an instance of MvcRouteHandler, which,
in turn, returns an MvcHandler that implements IHttpHandler. The MvcHandler is responsible
for instantiating the controller, which in turn calls the action method on that controller.