继续使用前面的例子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. 【转】sun.misc.BASE64Encoder找不到jar包的解决方法

    只需要在project build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了.(太神奇了,转自http://blog. ...

  2. 关于新装ubuntu系统update失败和build-essential失败的解决办法

    我是12月4日在新电脑上的vmware-workstation 10 上安装的ubuntu14.04LTS,但安装后再校园环境下总是build-essential失败,上网一查,说是要先update, ...

  3. hdu4753

    很简单的位模拟(bit-mask),可惜队友读题误以为很难,没有及时跟我交流,不然应该很早就可以出了. 很容易看出来,总共才16个点.24条边.用一个int类型数字就可以描述这个图了,按照16点的关系 ...

  4. leetcode Remove Element python

    class Solution(object): def removeElement(self, nums, val): """ :type nums: List[int] ...

  5. 有关MyISAM引擎的锁定机制

    本文介绍下,mysql数据库中MyISAM引擎的锁定机制的相关知识,感兴趣的朋友可以参考下. 本节内容: MyISAM引擎的锁定机制 在mysql数据库中,MyISAM存储引擎适合于读频率远大于写频率 ...

  6. 微软TTS示例

    #include "sphelper.h" #include "sapi.h" #pragma comment(lib, "sapi.lib" ...

  7. 幻世(OurDream)2D图形引擎易语言汉化版更新提示

    幻世引擎的易语言汉化专版到目前为止已经累积了多个BUG,其中多个BUG是影响引擎功能使用的问题,我将会在近期发布修复所有问题的更新版本(此更新版本同时也将会支持最新的对加入的粒子系统的支持),敬请各位 ...

  8. The method replace(int, Fragment, String) in the type FragmentTransaction is not applicable for the arguments (int, SettingFragment, String)

    The method replace(int, Fragment, String) in the type FragmentTransaction is not applicable for the ...

  9. Windows2008RT搭建VPN服务器

    总结一下2008系统搭建VPN的步骤和过程,自己有个人网站和服务要通过互联网发布出来.服务器放在自己家里,宽带是民用的.也就产生了服务发布的一些问题.用无法映射出真实的公网IP,或是一些其他内部的问题 ...

  10. windows命令行模式下无法打开python程序解决方法

    今天刚开始学Python,首先编写一个简单地hello world程序,想在命令行模式运行,结果出现下面: 经过一番思考,发现用cd命令可以解决这件事,看下图: 这样就解决了.