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
<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
routes.Add(new Route("SayHello", new CustomRouteHandler()));
访问SayHello,验证结果正确。
Asp.Net MVC4 系列--进阶篇之路由 (2)的更多相关文章
- Asp.Net MVC4 系列-- 进阶篇之路由(1)
创建一个路由 打开 RouteConfig.cs ,发现已经创建了一个默认路由 : routes.MapRoute( name:"Default", url:"{con ...
- Asp.Net MVC4 系列-- 进阶篇之路由
原文 http://blog.csdn.net/lan_liang/article/details/22993839 创建一个路由 打开 RouteConfig.cs ,发现已经创建了一个默认路由 ...
- Asp.Net MVC4 系列-- 进阶篇之路由(1)【转】
http://blog.csdn.net/lan_liang/article/details/22993839?utm_source=tuicool
- bootstrap-data-target触发模态弹出窗元素的data使用 data-toggle与data-target的作用 深入ASP.NET MVC之九:Ajax支持 Asp.Net MVC4系列--进阶篇之AJAX
bootstrap-data-target触发模态弹出窗元素的data使用 时间:2017-05-27 14:22:34 阅读:4479 评论:0 收藏:0 [ ...
- Asp.Net MVC 进阶篇:路由匹配 实现博客路径 和文章路径
Asp.Net MVC 进阶篇:路由匹配 实现博客路径 和文章路径 我们要实现 通过路由 匹配出 博客地址 和博客文章地址 例如下面的这两个地址 //http://www.cnblogs.com/ma ...
- SQL Server调优系列进阶篇(查询语句运行几个指标值监测)
前言 上一篇我们分析了查询优化器的工作方式,其中包括:查询优化器的详细运行步骤.筛选条件分析.索引项优化等信息. 本篇我们分析在我们运行的过程中几个关键指标值的检测. 通过这些指标值来分析语句的运行问 ...
- SQL Server调优系列进阶篇(深入剖析统计信息)
前言 经过前几篇的分析,其实大体已经初窥到SQL Server统计信息的重要性了,所以本篇就要祭出这个神器了. 该篇内容会很长,坐好板凳,瓜子零食之类... 不废话,进正题 技术准备 数据库版本为SQ ...
- SQL Server调优系列进阶篇(如何索引调优)
前言 上一篇我们分析了数据库中的统计信息的作用,我们已经了解了数据库如何通过统计信息来掌控数据库中各个表的内容分布.不清楚的童鞋可以点击参考. 作为调优系列的文章,数据库的索引肯定是不能少的了,所以本 ...
- SQL Server调优系列进阶篇(如何维护数据库索引)
前言 上一篇我们研究了如何利用索引在数据库里面调优,简要的介绍了索引的原理,更重要的分析了如何选择索引以及索引的利弊项,有兴趣的可以点击查看. 本篇延续上一篇的内容,继续分析索引这块,侧重索引项的日常 ...
随机推荐
- linux一周学习总结
对于linux,之前也完全没有接触过,完全零基础小白.来到马哥以后,进入学习也有一周时间 ,一周里老师带我们学习了很多指令,下面,我就自己的理解和老师讲授的内容对linux中的一些指令做一个简单的小总 ...
- 王者荣耀是怎样炼成的(一)《王者荣耀》用什么开发,游戏入门,unity3D介绍
在国内,如果你没有听说过<王者荣耀>,那你一定是古董级的人物了. <王者荣耀>(以下简称“农药”),专注于移动端(Android.IOS)的MOBA游戏.笔者看到这么火爆,就萌 ...
- Web应用程序的开发步骤
Web应用程序的开发步骤 如今已进入了web2.0高速发展的互联网时代,各种互联网的Web应用程序如雨后春笋般出现.那么作为一名Web开发人员,怎样去开发一款优秀的Web应用程序呢?这个问题没有一个简 ...
- Rsync for windows
说到电脑,我真是一屋子都是. 从房间到大厅,就已经有5台.这还没包括服务器. 虽然这5台电脑我最常用的也只是2~3台.其他的不是给朋友们来坐的时候打打游戏.就是给妈妈上网看看报纸. 不过我相信很多朋友 ...
- Window下SVN服务器搭建以及客户端使用
一.下载 上一篇博客是关于Jenkins的内容,在Jenkins自动化编译时可能会自动获取版本更新进行build,那就需要用到版本更新的工具.这里使用VisualSVN Server来作为搭建svn的 ...
- 团队作业8——Beta 阶段冲刺1st day
一.今日站立式会议照片 二.每个人的工作 (1) 昨天已完成的工作: 今天是冲刺的第一天,昨天完成的是团队成员任务的分配 (2) 今天计划完成的工作: 界面的完善 (3) 工作中遇到的困难: 对于界面 ...
- 团队作业8——第二次项目冲刺(Beta阶段)5.22
1.当天站立式会议照片 会议内容: ①:检查总结上次任务完成情况 ②:安排本次任务的分工 ③:反思前三次自己的不足 ④:协商解决代码进度.成员投入时间等问题 2.每个人的工作 工作中遇到的困难: 代码 ...
- 团队作业7——Alpha冲刺之事后诸葛亮(宣告项目失败团队解散)
一.项目进度 1.4月5日,团队组建.满怀希望的能做好这个项目 2.4月12日,需求分析. 3.4月21日,需求改进,出现协作问题,没有做好. 4.做项目,学习新的知识,继续做项目,但是能力有限,团队 ...
- 201521123109《java程序设计》第八周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 1.2 选做:收集你认为有用的代码片段 2. 书面作业 本次作业题集集合 List中指定元素的删除(题目4-1 ...
- 201521123038 《Java程序设计》 第七周学习总结
201521123038 <Java程序设计> 第七周学习总结 1. 本周学习总结 2. 书面作业 1.ArrayList代码分析 1.1 解释ArrayList的contains源代码 ...