当前位置: 首页 > news >正文

Asp.Net MVC4 系列--进阶篇之路由 (2)

上一篇介绍了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

<aclass="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,验证结果:

 


相关文章:

  • 探密Windows 7中的神秘隐藏分区
  • Asp.Net MVC系列--进阶篇之controller(1)
  • Windows 7下可以使用的虚拟光驱软件
  • Asp.Net MVC 系列--进阶篇之Filter
  • 10个非常有用的Windows 7优化调整技巧
  • Asp.Net MVC4 系列--进阶篇之Controller(2)
  • Windows 7快捷键及鼠标动作大全
  • C# 将多个Image 合成为一个,格式可选择
  • IE8 正式版(RTM) 的版本号: 8.0.6001.18702
  • Iori的工具箱 之 C# 实现多个图片合为一个Tiff
  • Asp.Net MVC4 系列--进阶篇之View
  • Xp+Windows 7硬盘安装 体验心得
  • Javascript 实现的StopWatch
  • Asp.Net MVC4系列--进阶篇之Helper(1)
  • 玻璃效果
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • HTML-表单
  • JDK9: 集成 Jshell 和 Maven 项目.
  • laravel 用artisan创建自己的模板
  • SpingCloudBus整合RabbitMQ
  • zookeeper系列(七)实战分布式命名服务
  • - 概述 - 《设计模式(极简c++版)》
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 前端代码风格自动化系列(二)之Commitlint
  • 前端知识点整理(待续)
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 我与Jetbrains的这些年
  • 一天一个设计模式之JS实现——适配器模式
  • ​插件化DPI在商用WIFI中的价值
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #ubuntu# #git# repository git config --global --add safe.directory
  • (1)SpringCloud 整合Python
  • (2.2w字)前端单元测试之Jest详解篇
  • (27)4.8 习题课
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (LeetCode 49)Anagrams
  • (第61天)多租户架构(CDB/PDB)
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (十六)一篇文章学会Java的常用API
  • (一)RocketMQ初步认识
  • (转) Face-Resources
  • (转载)利用webkit抓取动态网页和链接
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .NET多线程执行函数
  • .NET企业级应用架构设计系列之应用服务器
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录