Asp.Net MVC4 系列--进阶篇之路由 (2)
来源:互联网 发布:linux 除法 保留小数 编辑:程序博客网 时间:2024/05/29 13:23
上一篇介绍了Asp.Net MVC 中,从Http Pipeline上接收到请求如何匹配,匹配限制,以及如何控制在指定命名空间查找,解析出controller和action,并传参。
这篇主要介绍如何使用路由完成url生成,实现页面跳转,以及customize一个路由。
在view中生成一个url连接
路由配置使用默认生成的:
routes.MapRoute( name:"Default", url:"{controller}/{action}/{id}", defaults: new { controller ="Home", action = "Index", id = UrlParameter.Optional } );
最简单的方法是使用Html.ActionLink ,在home View里添加代码:
@{Layout = null;}<!DOCTYPE html><html><head><meta name="viewport"content="width=device-width" /><title>ActionName</title></head><body><div>The controller is:@ViewBag.Controller</div><div>The action is: @ViewBag.Action</div><div>@Html.ActionLink("This is an outgoing URL", "CustomVariable") </div></body></html>
这样就会生成:
<a href="/Home/CustomVariable">This is anoutgoing URL</a>
这样,实际上是生成了在当前controller内,指向另一个action的url。
使用Html.ActionLink生成链接的好处是什么,可以根据当前的路由配置,自动维护生成好的url,上例使用的是默认配置。例如如果路由配置改为:
routes.MapRoute("NewRoute","App/Do{action}",new { controller = "Home" });
使用同样的代码:
@Html.ActionLink("This is an outgoing URL","CustomVariable")
此时url连接就会生成为:
<a href="/App/DoCustomVariable">This is anoutgoing URL</a>
因为当我们访问home controller时,NewRoute 在默认路由之前被匹配到了,就会拿它的pattern来生成url了。
当一个请求来时,路由会检测:
1. Pattern
2. 路由限制
3. Assign给匿名对象的默认值,就是解析存在Route Dictionary 里面的那些值
跳转到其他controller
最简单的方式:
@Html.ActionLink("Thistargets another controller", "Index", "Admin")
直接传入第二个参数,指向”admin”controller
生成url连接,同时传参
对于同一个controller:
@Html.ActionLink("This is anoutgoing URL","CustomVariable", new {id = "Hello" })
跨controller传值:
@Html.ActionLink("Click me to go to anotherarea","Index", "Test",new {Id="aaa"},null)意,如果路由成功匹配了传值的参数名称,那么url就会以匹配的格式生成;如果路由匹配成功,可是传的值没有在路由模式中指定,那么就会以?param=value的形式传值。例如,对于以上actionlink,如果是路由:
routes.MapRoute("NewRoute","App/Do{action}",new { controller ="Home" })那么生成的url连接就是:
<a href="/Home/CustomVariable?id=Hello">This is an outgoingURL</a>如果对于路由:
routes.MapRoute("MyRoute","{controller}/{action}/{id}",new { controller ="Home", action = "Index",id = UrlParameter.Optional });那么生成的url就是:
<a href="/Home/CustomVariable/Hello">This is an outgoingURL</a>
设定html属性
简单的,还是同样使用Html.ActionLink:
@Html.ActionLink("This is anoutgoing URL","Index","Home", null, new {id = "myAnchorID",@class = "myCSSClass"})
这样就可以生成一个连接,class设为了myCssClass
<a class="myCSSClass"href="/"id="myAnchorID">This is an outgoing URL</a>生成一个绝对路径的url连接
@Html.ActionLink("This is anoutgoing URL", "Index", "Home","https","myserver.mydomain.com", " myFragmentName",new { id = "MyId"},new { id ="myAnchorID", @class = "myCSSClass"})生成:
<a class="myCSSClass"href="https://myserver.mydomain.com/Home/Index/MyId#myFragmentName"id="myAnchorID">This is an outgoing URL</a>
通常,不建议生成绝对路径的url,如需指向外部连接,可以直接使用html标签。
生成URL
有些场景,只需要生成一个连接,而不想和html.ActionLink建立耦合,那么就可以使用Url.Action:
@Url.Action("Index","Home", new { id = "MyId" })
对于默认route({controller}/{action}/{id})生成:
Home/Index/MyId
在action内生成url
public ViewResult MyActionMethod() {string myActionUrl = Url.Action("Index",new { id = "MyID" });string myRouteUrl =Url.RouteUrl(new { controller = "Home", action = "Index"});//... do something with URLs...return View();}
当然,更推荐简单的使用 RedirectToAction(),返回值为RedirectToRouteResult:
public RedirectToRouteResult MyActionMethod() {return RedirectToAction("Index");}
如果想跳出当前的controller,使用另一个重载:
public RedirectToRouteResult TestRedirect() { returnRedirectToAction("TestAction", "AnotherController"); }如果这个请求handle不掉,也不想跳到哪个controller,那就还给route吧(这种场景不多):
public RedirectToRouteResult MyActionMethod() {return RedirectToRoute(new {controller = "Home",action = "Index",id = "MyID" });}
自定义route system
如果当前route的行为还不能满足场景需要,那么可以自定义route,例如,对于刚从asp.netweb form移植到mvc上的网站,对于旧版本的url,我们也需要支持。
创建controller:
namespace UrlsAndRoutes.Controllers { public class LegacyController : Controller { public ActionResult GetLegacyURL(string legacyURL) { return View((object)legacyURL); } } }
这个controller接收传来的url,打印出当前的url(真正的行为应该是显示出该文件内容)。
View里面显示出controller拿来的url值:
@model string @{ ViewBag.Title = "GetLegacyURL"; Layout = null; } <h2>GetLegacyURL</h2> The URL requested was: @Model
完成了简单的controller和view,重点在于后面的route。
public class LegacyRoute : RouteBase { private string[] urls; public LegacyRoute(params string[] targetUrls) { urls = targetUrls; } public override RouteData GetRouteData(HttpContextBase httpContext) { RouteData result = null; string requestedURL = httpContext.Request.AppRelativeCurrentExecutionFilePath; if (urls.Contains(requestedURL, StringComparer.OrdinalIgnoreCase)) { result = new RouteData(this, new MvcRouteHandler()); result.Values.Add("controller", "Legacy"); result.Values.Add("action", "GetLegacyURL"); result.Values.Add("legacyURL", requestedURL); } return result; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { return null; }
创建一个类,继承了routeBase,重点在后面的那两个需要重写的方法:
GetRouteData和GetVirtualPath
对于getroutedata,我们做的操作时从httpcontext对象里拿当前的requesturl,如果是旧版本url里面的,那么直接就把controller指向legacy,action指向GetLegacyURL,并且把参数一起给了:LegacyURL设为当前的url。如果这个请求不是旧版本url里面,那么简单的返回null,让其他的route对象来handle吧。
对于GetVirtualPath,用于生产Url时,先简单的返回null,后面章节会介绍如何生成url。
最后,注册一下自定义的route:
routes.Add(new LegacyRoute( "~/articles/test1 ", "~/old/.NET_1.0_Class_Library"));
可以看到,自定义的route已经生效了。
在自定义route中生成URL
把刚才那个GetVirtualPath的函数做个简单实现:
public override VirtualPathData GetVirtualPath(RequestContext requestContext,RouteValueDictionary values) {VirtualPathData result = null;if(values.ContainsKey("legacyURL") &&urls.Contains((string)values["legacyURL"],StringComparer.OrdinalIgnoreCase)) {result = newVirtualPathData(this,new UrlHelper(requestContext).Content((string)values["legacyURL"]).Substring(1));}return result;}
函数功能:把传入的匿名对象的legacyURL的值做字符串截取,把首字符滤掉。
在view加入代码:
@Html.ActionLink("Clickme", "GetLegacyURL",new { legacyURL = "~/articles/Windows_3.1_Overview" })
就会生成:
<a href="/articles/Windows_3.1_Overview">Click me</a>
自定义Route Handler
前面的例子,我们都是用MvcRouteHandler,对于场景:http请求需要被httphandler来处理掉,那么就需要customize一个routehandler了。
1. 提供一个类继承IRouteHandler
public class CustomRouteHandler : IRouteHandler { public IHttpHandler GetHttpHandler(RequestContext requestContext) { return new CustomHttpHandler(); } }
2. 准备好HttpHandler
public class CustomHttpHandler : IHttpHandler { public bool IsReusable { get { return false; } } public void ProcessRequest(HttpContext context) { context.Response.Write("Hello"); } }
用于展示,这个handler拿到httpcontext后仅仅打印出hello。
3. 注册一个路由,对于相应的pattern,指向这个routehandler
utes.Add(newRoute("SayHello", new CustomRouteHandler()));routes.Add(new Route("SayHello", new CustomRouteHandler()));
routes.Add(new Route("SayHello", new CustomRouteHandler()));
访问SayHello,验证结果正确。
- Asp.Net MVC4 系列--进阶篇之路由 (2)
- Asp.Net MVC4 系列--进阶篇之路由 (2)
- Asp.Net MVC4 系列-- 进阶篇之路由(1)
- Asp.Net MVC4 系列-- 进阶篇之路由(1)
- Asp.Net MVC4 系列--进阶篇之Controller(2)
- Asp.Net MVC4 系列--进阶篇之Helper(2)
- Asp.Net MVC4 系列--进阶篇之Model(2)
- Asp.Net MVC4 系列--进阶篇之Model(1)
- Asp.Net MVC4 系列--进阶篇之View
- Asp.Net MVC4系列--进阶篇之Helper(1)
- Asp.Net MVC4系列--进阶篇之AJAX
- ASP.NET MVC4 系列教程之第二篇 (MVC4基础)
- Asp.Net MVC4 之Url路由
- Asp.Net MVC4 之Url路由
- Asp.Net MVC4系列---基础篇(4)
- Asp.Net MVC4系列---基础篇(5)
- Asp.Net MVC4 系列--基础篇(1)
- ASP.NET MVC4 系列教程之第三篇 (创建第一个MVC应用程序)
- 搞懂 res ->values + res ->drawable : 资源
- Linux下部署wowza流媒体HA文档
- 程序猿必知 — Android Support Library 23.2
- TCP 的三次握手 与 四次挥手详
- 生产者与消费者问题/有限缓冲问题
- Asp.Net MVC4 系列--进阶篇之路由 (2)
- No ulink device found肿么办
- JavaSE导论
- iOS Responder Chain
- xml解析-sax范例
- unity动态加载之AssetBundle应用
- Uva 514 (模拟stack)
- UDP与TCP的区别
- Android系统启动-init篇