转自: http://blog.csdn.net/lan_liang/article/details/22993839?utm_source=tuicool
创建一个路由
打开 RouteConfig.cs ,发现已经创建了一个默认路由 :
routes.MapRoute( name:"Default", url:"{controller}/{action}/{id}" //defaults: new { controller ="Home", action = "Index", id = UrlParameter.Optional } );
为了说明路由的url匹配过程,暂时comment掉default参数。
打开Global.cs ,可以看到路由配置文件已经注册:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
关于路由工作方式
Asp.net MVC Framework 的路由部分,是插入在http pipeline中的,当接受到http请求,会寻找注册的路由表(在ApplicationStart时候注册,就是应用启动时候),找到路由规则,获取每个路由规则的pattern,试图匹配当前请求合适的那个route,匹配成功,则解析出controller和action,从controllerfactory找到相应的controller,把请求传递给action,如果请求中传参,路由还会解析出参数,给action。
下面是几种url匹配的例子:
Controller =Admin,Action=Index |
|
Controller=Index,Action=Admin |
|
Controller=Apples,Action=Oranges |
|
匹配失败,Segment太少 |
|
http://mysite/Admin/Index/Soccer |
匹配失败,Segment太多 |
路由会调用route handler来完成路由过程,默认的,mvc应用会使用MVCRouteHandler.手动添加一个Route,就可以体现出来:
routes.Add("MyRoute",newRoute("{controller}/{action}", new MvcRouteHandler()));
指定默认(default)
刚才说明url匹配时候,拿掉了default参数,这时我们一起看看default参数的作用。
routes.MapRoute( name:"Default", url:"{controller}/{action}/{id}", defaults: new { controller = "Home", action ="Index", id = UrlParameter.Optional } );
可以看到最后一个参数,指定了一个默认的controller和action。
Mydomain.com |
Controller = Home ,action=Index |
Mydomain.com/Customer |
Controller=Customer ,action=Index |
Mydomain.com/Customer/List |
Controller=Customer, action=List |
Mydomain.com/Customer/List/All |
匹配失败,segment太多 |
定值Segment
场景1,所有请求中第一个Segment为”public”的,需要统一处理,因此定义一个路由:
routes.MapRoute(name: "PublicReqRoute", url:"Public/{controller}/{action}", defaults: new {controller = "PublicHome", action ="Index"});
示例url:http://mysite/Public
匹配结果:controller = PublicHome,action=Index
场景2,请求中以public开始的,需要统一处理,定义路由:
示例url: Http:/mysite/PublicX/
匹配结果:controller=X,action=Index
routes.MapRoute(name: "PublicReqRoute", url:"Public{controller}/{action}", defaults: new {controller = "PublicHome", action ="Index"});
场景3:有个controller或action不工作,需要改个bug,把所有原来指向这个controller的请求暂时路由到首页:
routes.MapRoute("myshop","Shop/OldAction", new { controller = "Home", action ="Index" });
注意:路由是按着添加顺序依次解析的,因此把最特殊的那个路由放在前面,避免先fall 到相对generall的那个。
获取参数
对于Route:
routes.MapRoute( name:"Default", url:"{controller}/{action}/{id}", defaults: new { controller = "Home", action ="Index", id = UrlParameter.Optional } );
请求:http://mysite/Home/Index/15
Action 中使用RouteData.Values获取传入的id:
public ActionResult CustomVariable() { ViewBag.Controller = "Home"; ViewBag.Action = "CustomVariable"; ViewBag.CustomVariable = RouteData.Values["id"]; return View(); }
使用mvcframework Route System自动传参机制
除了使用RouteData.Values取出传入的参数,可以更简单的定义个参数在action,但是参数名要和route定义的相同(id)
Public ActionResult CustomVariable(string id) { ViewBag.Controller = "Home"; ViewBag.Action = "CustomVariable"; ViewBag.CustomVariable = id; return View(); }
对于url:http://mysite/Home/Index/15,id就会自动被赋值为15传入action
定义可选参数
依然对于url:
routes.MapRoute( name:"Default", url:"{controller}/{action}/{id}", defaults: new { controller = "Home", action ="Index", id = UrlParameter.Optional } );
Id=UrlParameter.Optional,此时id就是可选参数
Mydomain.com |
Controller=home ,action=Index |
Mydomain.com/customer |
Controller=customer, action=Index |
Mydomain.com/customer/List |
Controller=customer, action=List |
Mydomain.com/customer/List/All |
Controller=customer , action=List, Id=All |
Mydomain.com/customer/List/All/Delete |
url 匹配失败 |
如果没有传参,action提供了id参数,那么id此时就为null;
public ActionResultCustomVariable(string id) { ViewBag.Controller = "Home"; ViewBag.Action = "CustomVariable"; ViewBag.CustomVariable = id == null ? "<novalue>" : id; return View(); }
作为另一个选择,可以指定一个默认参数,如果没url没传值,默认参数值就会被使用。
Public ActionResultCustomVariable(string id = "DefaultId") { ViewBag.Controller = "Home"; ViewBag.Action = "CustomVariable"; ViewBag.CustomVariable = id; return View(); }
使用{*catchall}捕捉超出数量的segment
例如,对于这条route:
routes.MapRoute("MyRoute","{controller}/{action} /{*catchall}", new { controller = "Home", action ="Index", id = UrlParameter.Optional });
由于使用了{*catchall},对于url:
http://mysite/Home/Index/All/More/More/More
此时,controller=Home,Action=Index, catchall=”All/More/More/More”
这样,就把解析剩下segment的工作交给了自己处理
解决在不同namespace的同名controller
例如现在有两个controller,在不同的命名空间:
namespace UrlsAndRoutes.Controllers { public class HomeController : Controller { public ActionResult Index() { ViewBag.Controller = "Additional Controllers - Home"; ViewBag.Action = "Index"; return View("ActionName"); } } }
和
namespace UrlsAndRoutes.AdditionalControllers { public classHomeController : Controller { public ActionResultIndex() { ViewBag.Controller = "Additional Controllers -Home"; ViewBag.Action = "Index"; return View("ActionName"); } } }
对于这种情况,可能希望路由先在一个指定的命名空间里找,找到了返回:
routes.MapRoute("MyRoute","{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action ="Index", id = UrlParameter.Optional }, new[] { "URLsAndRoutes.AdditionalControllers" });
关键在于最后的那个命名空间参数,mvc framework会优先找 “URLsAndRoutes.AdditionalControllers”里面的controller,如果没找到,会搜索其余的命名空间。
注意,这个new []{}数字里的参数是平行的,也就是说,如果mvc framework在这些命名空间里找到多个同名controller,不会找到第一个就返回,依然会抛出异常,例如:
new[] { "URLsAndRoutes.AdditionalControllers","UrlsAndRoutes.Controllers"});
对于url:
mvc framework会在指定的命名空间数组里找,由于找到了多个homecontroller,因此抛出异常。
如果希望这样:指定多个命名空间,找到了第一个就返回,怎么做?
可以配置多条route:
routes.MapRoute("AddContollerRoute","Home/{action}/{id}/{*catchall}", new { controller = "Home", action ="Index", id = UrlParameter.Optional }, new[] { "URLsAndRoutes.AdditionalControllers" }); routes.MapRoute("MyRoute","{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action ="Index", id = UrlParameter.Optional }, new[] { "URLsAndRoutes.Controllers" });
mvc framework就会按着添加的顺序依次查找匹配的controller和action,找到了把解析好的参数(如果有)传递给action就返回了。
只允许mvc framework在指定的 namespace里找,如何做?
Route myRoute=routes.MapRoute("AddContollerRoute", "Home/{action}/{id}/{*catchall}", new { controller = "Home", action ="Index", id = UrlParameter.Optional }, new[] { "URLsAndRoutes.AdditionalControllers" }); myRoute.DataTokens["UseNamespaceFallback"] = false;
由于把DataTokens[“UseNamespaceFallback”] 设为false,因此mvcframework在指定的命名空间:URLsAndRoutes.AdditionalControllers"里面找完了,就不去其他地方找了。
给路由加限制
正则限制
可以加正则限制在controller和action:
routes.MapRoute("MyRoute","{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action ="Index", id = UrlParameter.Optional }, new { controller = "^H.*"}, new[] { "URLsAndRoutes.Controllers"});
由于给controller加上了正则表达式:”^H.*”的限制,因此对于url匹配了urlpattern,解析出controller,如果不是以H开头的,也会被过滤掉。
类似的,也可以使用给action加正则限制:
new { controller = "^H.*", action ="^Index$|^About$"}
这样,就限制了action必须是Index和About。
使用Http Method限制
可以限制请求是Get ,Post亦或是Put ,Delete等类型的。
new { controller = "^H.*", action ="Index|About", httpMethod = new HttpMethodConstraint("GET") } ,
这样,就限制了请求必须是Get方式的。
注意,给route加httpmethod限制,和给controller还有action加httpmethod区别在于,route在httppipeline很早的位置就被处理了,而到controller和action的时候,已经是httppipeline很晚的时候了,controller和action已经被解析了,参数也已经被解析了(如果有)。
自定义限制
Mvc 提供了IRouteConstranit 接口,可以自己定义限制,通过实现这个接口:
public class UserAgentConstraint : IRouteConstraint { private string requiredUserAgent; public UserAgentConstraint(string agentParam) { requiredUserAgent = agentParam; } Public boolMatch(HttpContextBase httpContext, Routeroute, string parameterName, RouteValueDictionary values,RouteDirection routeDirection) { return httpContext.Request.UserAgent != null && httpContext.Request.UserAgent.Contains(requiredUserAgent); } }
以上代码,实现了一个限制,必须Request对象中的代理对象不为空,也就是必须使用代理才能访问,并且代理名称包含指定的名称。
使用自定义限制:
routes.MapRoute("ChromeRoute","{*catchall}", new { controller = "Home", action ="Index" }, new { customConstraint = newUserAgentConstraint("Chrome") }, new[] { "UrlsAndRoutes.AdditionalControllers" });
这样,就实现了,必须使用chrome才能访问的限制。
让访问物理文件目录的请求也参与路由
默认情况下,route system会先检查url是否指向了一个物理文件目录,如果是,返回找到这个文件,返回;否则,执行注册到路由表里面的每一条route。也就是说,指向物理文件目录的请求实际在mvc路由机制之前已经被处理掉了,默认没有参与路由。
如果要改变这个行为,例如访问
http://mysite/resource/pic/ ,不希望route去找resource/pic物理目录,而希望route找resourcecontroller ,pic action,那么:
在注册路由时,加上
routes.RouteExistingFiles = true;
这样,本地文件的检测 就会在路由机制执行之后了。
在路由前后,httppipeline的示意图
其中,httpmodule 1和 httpmodule2 在pipeline上面routesystem前后的两个module。
加上route.RouteExistingFiles=true
Route system中,就会先执行MVC Route,后执行CheckDisk Files .最后,为物理文件指定一个route:
routes.MapRoute("DiskFile","Content/StaticContent.html", new { controller = "Resource", action = "List", });
By Passing Route System
有些访问资源文件的请求,是需要ignore的,这种需求直接用ignoreRoute就可以了:
routes.IgnoreRoute("Content/{filename}.html");
这样,对于url:http://mysite/Content.test.html 的请求就被route忽略了,访问页面,就会出现资源无法找到和404错误:
HTTP Error 404.0 - Not Found
The resource you are looking for has beenremoved, had its name changed, or is temporarily unavailable.
相关推荐
标题中的“asp.net mvc demo”表明这是一个关于ASP.NET MVC的演示或实例项目,可能包括了从基础到进阶的各种功能和用例。描述中的“2015-08-25”可能是这个项目开始或完成的日期,也可能是每天学习计划的一部分。 ...
1. **身份验证和授权** - ASP.NET MVC 5 引入了新的身份验证系统,基于Owin和Katana中间件,支持OAuth 2.0和OpenID Connect。这使得开发者可以轻松集成社交登录服务,如Facebook、Google等。 2. **Bootstrap 支持**...
这本书可能涵盖了从初学者入门到高级进阶的所有主题,包括如何使用ASP.NET MVC4搭建项目、设计模型、编写控制器、创建视图、实现验证、部署应用等。对于想要学习或提升ASP.NET MVC4开发技能的读者来说,这是一本极具...
ASP.NET MVC5高级编程(第5版.NET开发经典名著)作为Microsoft备受欢迎的MVC技术的最新版本,MVC 5是一个成熟的Web应用程序框架,支持快速的、TDD友好的开发。MVC允许开发人员创建动态的、数据驱动的网站。这样的...
总的来说,《Pro Asp.net MVC4》这本书全面地涵盖了ASP.NET MVC 4的关键概念和技术,为开发者提供了从理论到实践的深入学习资源,是ASP.NET MVC初学者和进阶者不可多得的参考书籍。通过阅读和实践书中的内容,读者...
这本书是ASP.NET MVC开发者进阶的宝贵资源,无论你是初学者还是有经验的开发者,都能从中受益。通过深入学习和实践书中的案例,你将能够熟练掌握ASP.NET MVC 5的高级特性和最佳实践,从而提高你的Web开发技能。
2. **路由**:了解ASP.NET MVC中的URL路由机制,如何配置默认路由和自定义路由。 3. **控制器和动作**:编写控制器类,定义处理HTTP请求的动作方法。 4. **视图**:创建和使用Razor视图来渲染HTML,以及如何使用视图...
1. **路由系统**:ASP.NET MVC4提供灵活的路由规则,可以自定义URL结构,使URL更符合SEO需求。 2. ** Areas**:大型项目中,可以使用Areas进行模块化管理,每个Area可以视为一个独立的小应用。 3. **azor视图引擎*...
1. **[ASP.NET.MVC系列].ASPNETMVCQuickly.pdf**:这本书可能是快速入门ASP.NET MVC的指南,旨在帮助初学者迅速掌握基本概念和关键功能,例如路由、控制器、视图、模型绑定等。 2. **[ASP.NET.MVC系列]....
以上是"ASP.NET Core MVC从入门到精通"系列文章的主要知识点,涵盖了从基础到进阶的全过程,是学习ASP.NET Core MVC不可或缺的资源。通过这个系列的学习,开发者可以全面掌握构建高效、可扩展的Web应用所需的技能。
### ASP.NET MVC 4 关键知识点解析 #### 一、ASP.NET MVC 4 概述 **ASP.NET MVC 4** 是微软推出的一种基于模型-视图-控制器(Model-View-Controller)架构模式的框架,用于开发动态、可维护性强的Web应用程序。此...
1. **权威性**:本书由经验丰富的专家撰写,内容经过精心策划和组织,是学习ASP.NET MVC框架的必备参考书之一。 2. **实用性**:除了理论讲解外,本书还提供了大量实用的示例代码和最佳实践,有助于开发者快速上手并...
### 专业 ASP.NET MVC 4 知识点详解 #### 一、概述 《Professional ASP.NET MVC 4》是一本全面介绍ASP.NET MVC 4框架的专业书籍,由Jon Galloway、Phil Haack、Brad Wilson及K. Scott Allen等多位在.NET社区中享有...
尽管原文为英文版本,但其内容详实、易于理解,被广泛认为是学习ASP.NET MVC2的最佳资料之一。本书不仅适合初学者快速入门,也为进阶学习提供了坚实的基础。 #### 二、ASP.NET MVC2 概述 ASP.NET MVC(Model-View-...
- **URL 路由与区域划分**:URL 路由是 ASP.NET MVC 中的一项重要技术,它允许开发者自定义 URL 的格式,而区域则可以将应用分成多个独立的部分,便于管理和扩展。 - **控制器与操作方法**:控制器是 MVC 模式中的...
本书首先会介绍Asp.NET MVC 5的基本概念,包括模型-视图-控制器(MVC)设计模式、路由系统和依赖注入。模型部分,将详细讨论如何创建数据模型类,使用Entity Framework进行数据库交互,以及如何应用验证规则。视图...
ASP.NET MVC 是微软提供的一种基于...通过这个"asp.net MVC 实例",你可以亲手实践以上知识点,从基础到进阶,全面掌握ASP.NET MVC的开发技能。在实际操作中,你将更深刻地理解MVC模式如何提升Web开发的效率和质量。
### ASP.NET MVC2 知识点详解 #### 一、ASP.NET MVC2 概述 ASP.NET MVC2 是一种用于构建动态网站的应用程序框架,它遵循模型-视图-控制器(Model-View-Controller)的设计模式。这种模式有助于将业务逻辑、用户...
总的来说,【ASP.NET.MVC系列].ASPNETMVCQuickly.pdf 这个教程可能会引导读者从基础到进阶,全面了解并掌握如何利用ASP.NET MVC框架构建高效、可扩展的Web应用程序。通过学习,开发者不仅可以理解MVC模式的工作原理...