继续使用前面的例子11-3URLTestDemo,修改Global.asax中的RegisterRoutes方法如下:

        public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
new { Controller = "Home", Action = "Index", id = UrlParameter.Optional },
new[] { "_11_3URLTestDemo.Controllers" });
}

1、手工定义URL

在某些情况下可以直接手工定义url

假设在HomeController中有方法About:

        public ViewResult About()
{
return View();
}

并为它添加了对应的默认视图Views/Home/About.cshtml

@{
ViewBag.Title = "About";
} <h2>About</h2>

现在,在HomeController中有方法Index:

        public ViewResult Index(string id)
{
//ViewBag.id = RouteData.Values["id"];
ViewBag.id = id;
return View();
}

并添加了对应的视图Views/Home/Index.cshtml

@{
ViewBag.Title = "Index";
} <h2>ID: @ViewBag.id</h2>
<p>
<a href="/Home/About">About this application</a>
</p>

这里的<a href="/Home/About">About this application</a>就是手工产生了一个url,指向"~/Home/About",在本项目中任何cshtml文件直接这样编码,都可以产生一个"~/Home/About"的url,无论是否跟About在同一个控制器中、无论论是否跟About在同一层次。

2、在视图中生成输出URL(使用ActionLink)

在刚才的Views/Home/Index.cshtml中使用:

@Html.ActionLink("About this application", "About")

第一个参数是链接文本,第二个参数是生成当前视图的控制器里的目标方法名。需要注意的是,ActionLink所生成的Html是基于当前路由方案的。如果定义的路由是:

        public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
new { Controller = "Home", Action = "Index", id = UrlParameter.Optional },
new[] { "_11_3URLTestDemo.Controllers" });
}

注意,没有{*catchall},这种路由定义下,@Html.ActionLink("About this application", "About")就会正常生成Html和超链接如下:

<a href="/Home/About">About this application</a>

但是,这里有个问题尚未解决,如果路由定义是跟本文开头一样的:

        public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
new { Controller = "Home", Action = "Index", id = UrlParameter.Optional },
new[] { "_11_3URLTestDemo.Controllers" });
}

有{*catchall},这种路由定义下,@Html.ActionLink("About this application", "About")就不能正常生成超链接,超链接是空的:

<a href="">About this application</a>

ActionLink所生成的Html是基于当前路由方案,另一个例子是,不改变视图中ActionLink的调用,通过修改路由,来生成匹配的路由的Html和超链接。

例如,修改路由定义:

        public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("NewRoute", "App/Do{action}",
new { Controller = "Home" }); routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
new { Controller = "Home", Action = "Index", id = UrlParameter.Optional },
new[] { "_11_3URLTestDemo.Controllers" });
}

那么@Html.ActionLink("About this application", "About")就会生成:

<a href="/App/DoAbout">About this application</a>

但是需注意的是,点击生成的url,按照顺序,匹配的是第一个路由定义,此时控制器仍是Home,动作方法还是About。也就是现在"~/App/DoAbout"和"~/Home/About"访问到的是同一个页面。可以通过这种方法隐藏真实的controller和action,或者说在controller和action发生变化后,可以通过这种方式来维护旧有的url。而修改路由方案后,视图中的输出链接会自动反映出这种修改。

============

使用ActionLink在视图中生成输出URL(注意生成什么样的url)

(1)假如路由是如下定义:

        public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
new { Controller = "Home", Action = "Index", id = UrlParameter.Optional },
new[] { "_11_3URLTestDemo.Controllers" });
}

在Views/Home/Index.cshtml中使用:

@Html.ActionLink("About this application", "About")

首先,需要知道使用ActionLink的视图是由哪个控制器产生的。这里使用ActionLink的Index.cshtml视图,是由控制器Home中的Index动作方法产生的默认视图。当我们在Index.cshtml视图中使用ActionLink时,它的第一个参数给出了超链接文本,第二个参数给出了目标Aciton,并没有给出目标Controller,这时使用的目标控制器,就是产生当前视图的控制器Home。也就是说,生成的url被点击后,要访问的就是Home控制器里的About动作方法。分析出目标控制器和动作方法后,再将其跟定义的路由进行匹配,反向推导出如果要访问这样的控制器和动作方法,那么它的url地址应该是什么形态。本例中目标Controller为Home,目标Action为About,目标id没有,因为id设置有UrlParameter.Optional属性,所以没有给出id的值时,就没有id变量。而控制器和动作方法在url模式中都有显式变量{controller}和{action}。因此,用控制器的值Home,和动作方法的值About,id变量没有就表示没有值,反推回去,得到生成的url为"~/Home/About"

(2)假设对于跟上面相同的路由定义,在Views/Account/LogOn.cshtml中使用:

@Html.ActionLink("About this application", "About")

这里使用ActionLink的视图是由控制器Account产生的,因此,这里的ActionLink产生的目标控制器是Account,目标动作方法是About,没有id。匹配路由,反向还原路由定义中的url模式{controller}/{action}/{id},得到生成的url为"~/Account/About"

(3)修改路由定义为:

        public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("NewRoute", "App/Do{action}",
new { Controller = "Home" }); routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
new { Controller = "Home", Action = "Index", id = UrlParameter.Optional },
new[] { "_11_3URLTestDemo.Controllers" });
}

在Views/Home/Index.cshtml中使用:

@Html.ActionLink("About this application", "About")

使用ActionLink的视图由控制器Home产生,因此,ActionLink生成的目标控制器为Home,目标动作方法为About。有两条路由的定义,按照顺序,先看第一条是否匹配。第一条路由的url模式"App/Do{action}"中,没有出现变量"{controller},那么控制器变量就成为了匿名类型,反向还原生成url时,只有Controller的值等于"Home",才匹配这条路由。而当前ActionLink生成的目标控制器为Home,目标动作方法为About,跟第一条路由匹配,反向还原url,将动作方法的值About带入动作方法变量{action},得到生成的url为"~/App/DoAbout"。

当用户点击生成后的url"~/App/DoAbout"时,它又正向匹配第一个路由,解析出目标Controller为Home,目标Action为About。点击此url后,执行HomeController里的About动作方法。

(4)对于跟(3)相同的路由定义,在Views/Account/LogOn.cshtml中使用:

@Html.ActionLink("About this application", "About")

LogOn.cshtml视图由控制器Account产生,因此,ActionLink生成的目标控制器为Account,目标动作方法为About。对定义的两条路由,首先试图跟第一条路由匹配,但是不匹配,因为第一条路由在反向匹配时,只有当控制器为Home时才匹配。

所以,本次ActionLink产生的结果匹配第二条路由,反向还原,得到生成的url为"~/Account/About"

3、使用ActionLink,同时指定Action和Controller

在Views/Home/Index.cshtml中使用:

@Html.ActionLink("LogOn", "LogOn", "Account")

多加一个参数,第三个参数表示指定的控制器。生成的url为"~/Account/LogOn"

4、使用ActionLink传递除了Action和Controller以外的值

HomeController里有方法Index:

        public ViewResult Index(string id)
{
ViewBag.id = id;
return View();
}

Views/Home/Index.cshtml定义如下:

@{
ViewBag.Title = "Index";
} <h2>ID: @ViewBag.id</h2>
<p>
@Html.ActionLink("Index with id", "Index", new { id="ABC"})
</p>

(1)

如果路由定义为:

        public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
new { Controller = "Home", Action = "Index", id = UrlParameter.Optional },
new[] { "_11_3URLTestDemo.Controllers" });
}

则@Html.ActionLink("Index with id", "Index", new { id="ABC"})生成的url为"~/Home/Index/ABC"

(2)

如果路由定义为:

        public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("NewRoute", "App/Do{action}",
new { Controller = "Home" }); routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
new { Controller = "Home", Action = "Index", id = UrlParameter.Optional },
new[] { "_11_3URLTestDemo.Controllers" });
}

则@Html.ActionLink("Index with id", "Index", new { id="ABC"})生成的url为"~/App/DoIndex?id=ABC"

另,当给属性提供的值与片段变量不一致时,这些值将作为查询字符串被添加到生成的输出url上。假设路由定义与(1)相同,在Views/Home/Index.cshtml中有@Html.ActionLink("Extra value", "About", new { id="ABC", myVariable="MyValue"})

生成的url为"~/Home/About/ABC?myVariable=MyValue"

5、指定html标签属性

使用ActionLink生成url,可以指定标签属性,只需要通过new建立一个匿名类型(匿名的类型是指在路由定义的url模式中,没有对应的片段变量),新建的匿名类型内给出的属性名与所需要的标签属性名相同即可。

例如,对于路由定义:

        public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
new { Controller = "Home", Action = "Index", id = UrlParameter.Optional },
new[] { "_11_3URLTestDemo.Controllers" });
}

在Views/Home/Index.cshtml中使用ActionLink:

@Html.ActionLink("HyperLink with attribute", "Index", "Home", null, new { id="myAnchorID", @class = "myCSSClass" })

注意这里的几个参数,null表示除了前面"Index"和"Home"对应的片段变量外,后面的片段变量都没有值。

最后一个参数用new新建了匿名类型,具有id和class属性,生成的html:

<a class="myCSSClass" href="/" id="myAnchorID">HyperLink with attribute</a>

这样,当前标签<a>的样式效果就可以由myCSSClass来决定。

6、ActionLink生成全限定url

@Html.ActionLink("HyperLink with attribute", "Index", "Home", "https", "myserver.mydomain.com", "myFragmentName", new{id="MyId"}, new { id="myAnchorID", @class = "redlink" })

生成的html为:

<a class="myCSSClass" href="https://myserver.mydomain.com/Home/Index/MyId#myFragmentName" id="myAnchorID">HyperLink with attribute</a>

7、生成url字符串(而不是链接)

可以使用Url.Action方法只生成url字符串,而不生成html元素。例如:

my url is:@Url.Action("Index", "Home", new{id="MyId"})

在视图中的产生的结果为:

my url is:/Home/Index/MyId

8、也可使用RouteLink和Routeurl

@Html.RouteLink("Route Link", new { controller="Home", action="About", id="MyID" })

生成的html为:

<a href="/Home/About/MyID">Route Link</a>

也可用Url.RouteUrl来生成url字符串,而不是html元素。

@Html.RouteUrl(new { controller="Home", action="About", id="MyID" })

9、在动作方法中生成url字符串

假设有路由定义:

        public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
new { Controller = "Home", Action = "Index", id = UrlParameter.Optional },
new[] { "_11_3URLTestDemo.Controllers" });
}

在HomeController.cs中有动作方法Index:

public ViewResult Index(string id)
{
ViewBag.id = id;
string myActionUrl = Url.Action("Index", new { id = "MyID" });
string myRouteUrl = Url.RouteUrl(new { Controller = "Home", action = "Index" });
return View();
}

生成url字符串,根据路由反推

myActionUrl的内容为:"/Home/Index/MyID"

myRouteUrl的内容为:"/"

10、将客户端的请求重定向到另一个url

(1)使用RedirectToAction

假设路由定义如9中所示,在HomeController.cs中有动作方法RedirectTest:

        public ActionResult RedirectTest()
{
return RedirectToAction("Index");
}

根据路由定义,反向推导,RedirectToAction("Index")生成的url是"/Home/Index"

当客户端在浏览器上请求"~/Home/RedirectTest"时,就被重定向到"~/Home/Index"

(2)使用RedirectToRoute

假设上面例子中的RedirectTest动作方法定义如下:

        public ActionResult RedirectTest()
{
return RedirectToRoute(new { controller="Home", Action="Index", id="MyID"});
}

RedirectToRoute(new { controller="Home", Action="Index", id="MyID"})生成的url是"/Home/Index/MyID"

11、用指定的路由定义来生成url

路由是按其定义的顺序,从上往下依次匹配的。在生成输出url时,根据路由定义反向推导出url,也是按路由定义顺序,从上往下进行匹配。例如,当路由定义如下时:

routes.MapRoute("MyRoute", "{controller}/{action}");

routes.MapRoute("MyOtherRoute", "App/{action}", new{ controller="Home" });

如果按照这样的顺序,那么下面用ActionLink:

@Html.ActionLink("Click me", "About");

在产生输出url时,匹配的路由总是第一条MyRoute。

可以用Html.RouteLink来指定要使用的路由:

@Html.RouteLink("Click me", "MyOtherRoute", new{ action = "About" });

-lyj

生成输出url的更多相关文章

  1. 生成输出url时,使用CSS来控制超链接的格式

    在前文<生成输出url>中的第5点,介绍了使用ActionLink生成输出url中指定html标签属性. 例如, 假设Global.asax中的路由定义为: public static v ...

  2. 生成输出 URL(16.2)

    1.在视图中生成输出 URL 几乎在每一个 MVC 框架应用程序中,你都会希望让用户能够从一个视图导航到另一个视图 —— 通常的做法是在第一个视图中生成一个指向第二个视图的链接,该链接以第二个视图的动 ...

  3. mvc 生成输出url

    最近一直在学习mvc,其中对于 Url.Action生成的url感到很困惑.官方的解释的基于路由方案生成的url.问题是,怎样基于,怎样选择,没有过多的解释.网上找了很多资料,也看不懂,最后还是在pr ...

  4. 生成链接中的全限定URL(Generating Fully Qualified URLs in Links) | 在视图中生成输出URL | 高级路由特性

    结果:<a class="myCSSClass"href="https://myserver.mydomain.com/Home/Index/MyId#myFrag ...

  5. 指定HTML标签属性 |Specifying HTML Attributes| 在视图中生成输出URL |高级路由特性 | 精通ASP-NET-MVC-5-弗瑞曼

    结果呢: <a class="myCSSClass" href="/" id="myAnchorID">This is an o ...

  6. 传递额外的值 Passing Extra Values |在视图中生成输出URL | 高级路由特性 | 精通ASP-NET-MVC-5-弗瑞曼

    结果呢 <a href="/App/DoCustomVariable?id=Hello">This is an outgoing URL</a> 理解片段变 ...

  7. 用路由系统生成输出URL 在视图中生成输出URL 高级路由特性 精通ASP-NET-MVC-5-弗瑞曼

    Using the Routing System to Generate an Outgoing URL 结果呢:<a href="/Home/CustomVariable" ...

  8. 根据指定路由生成URL |Generating a URL from a Specific Route | 在视图中生成输出URL|高级路由特性

    后面Length=5 是怎么出现的?

  9. 在动作方法中生成输出URL (Generating Outgoing URLs in Action Methods) |

随机推荐

  1. SqlServer之触发器

    1.触发器之理论: 触发器(Trigger)是一种特殊类型的存储过程,是在用户对某一种表的数据进行UPDATE.INSERT 和 DELETE 操作时被触发执行的一段程序.触发器有助于强制引用完整性, ...

  2. JSON、XML 解析

    iOS开发--XML/JSON数据解析 不错的文章http://www.jianshu.com/p/a54d367adb2a

  3. TCP为什么需要3次握手与4次挥手

    为什么需要“三次握手” 在谢希仁著<计算机网络>第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”.在另一部经典的<计算机网络> ...

  4. 查看mysql字符集及修改表结构

    MySQL 乱码的根源是的 MySQL 字符集设置不当的问题,本文汇总了有关查看 MySQL 字符集的命令.包括查看 MySQL 数据库服务器字符集.查看 MySQL 数据库字符集,以及数据表和字段的 ...

  5. OC语法2——OC的类,方法,成员变量的创建

    类的创建: 与Java不同的是,OC创建一个类需要两个文件(.h和.m文件) 1> xxx.h:声明文件.用于声明成员变量和方法.关键字@interface和@end成对使用. 声明文件只是声明 ...

  6. 使用ajax异步提交表单

    虽然这篇文章的标题是提交表单,但是主要的难点在于使用ajax提交文本域的内容, 在工作中的经常会需要ajax跨域的问题,通常的需求使用jsonp就可以得到解决,但是当前项目中有一个图片服务器,客户端需 ...

  7. Java中Overload和Override的区别

    由于项目正式收工,闲来无事突然发现以前的文档上有一个问题介绍的不是很详细 override(重写,覆盖) ​​ 1.方法名.参数.返回值相同. ​2.子类方法不能缩小父类方法的访问权限. 3.子类方法 ...

  8. Java生成缩略图之Thumbnailator

    Thumbnailator 是一个为Java界面更流畅的缩略图生成库.从API提供现有的图像文件和图像对象的缩略图中简化了缩略过程,两三行代码就能够从现有图片生成缩略图,且允许微调缩略图生成,同时保持 ...

  9. objective -c こだわり

    You make an object by creating an instance of a particular class. You do this by allocating the obje ...

  10. 今天在发布IIS站点的时候遇到了一些问题

    1.HTTP 错误 500.23 - Internal Server Error 检测到在集成的托管管道模式下不适用的 ASP.NET 设置. 分析:一般5XX的错误都是服务器的问题,这里把应用程序池 ...