ASP.NET MVC路由扩展:链接和URL的生成
ASP.NET 路由系统通过注册的路由表旨在实现两个“方向”的路有功能,即针对入栈请求的路由和出栈URL的生成。前者通过调用代表全局路由表的RouteCollection对象的GetRouteData方法实现,后者则依赖于RouteCollection的GetVirtualPathData方法,而最终还是落在继承自RouteBase的路由对象的同名方法的调用上。为了编程的方面,ASP.NET MVC为了设计了HtmlHelper和UrlHelper这两个帮助类,我们可以通过调用它们的ActionLink/RouteLink和Action/RouteUrl根据注册的路有规则生成链接或者URL。从本质上讲,HtmlHelper/UrlHelper实现的对URL的生成最终还是依赖于上面所说的GetVirtualPathData方法。
目录
一、UrlHelper V.S. HtmlHelper
二、UrlHelper.Action V.S. HtmlHelper.ActionLink
三、实例演示:创建一个RouteHelper模拟UrlHelper的URL生成逻辑
四、UrlHelper.RouteUrl V.S. HtmlHelper.RouteLink
一、UrlHelper V.S. HtmlHelper
在介绍如果通过HtmlHelper和UrlHelper来生成链接或者URL之前,我们来先来看看它们的基本定义。从下面给出的代码片断我们可以看出UrlHelper对象实际上对一个表示请求上下文的RequestContext和路由对象集合的RouteCollection对象的封装。它们分别对应于只读属性RequestContext和RouteCollection,并且在构造函数中被初始化。如果在构造UrlHelper的时候没有指定RouteCollection对象,那么通过RouteTable的静态属性Routes表示的全局路有表将直接被使用。
1: public class UrlHelper
2: {
3: //其他成员
4: public UrlHelper(RequestContext requestContext);
5: public UrlHelper(RequestContext requestContext, RouteCollection routeCollection);
6:
7: public RequestContext RequestContext { get; }
8: public RouteCollection RouteCollection { get;}
9: }
再来看看如下所示的HtmlHelper的定义,它同样具有一个表示路由对象集合的RouteCollection属性。和UrlHelper一样,如果在构造函数没有显示指定,那么RouteTable的静态属性Routes表示的RouteCollection对象将会用于初始化该属性。
1: public class HtmlHelper
2: {
3: //其他成员
4: public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer);
5: public HtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection);
6:
7: public RouteCollection RouteCollection { get; }
8: public ViewContext ViewContext { get; }
9: }
10: public class ViewContext : ControllerContext
11: {
12: //省略成员
13: }
14: public class ControllerContext
15: {
16: //其他成员
17: public RequestContext RequestContext { get; set; }
18: public virtual RouteData RouteData { get; set; }
19: }
由于HtmlHelper只要在View中使用,所以它具有一个通过ViewContext属性表示的针对View的上下文。至于该属性对应的类型ViewContext,它是表示Controller上下文的ControllerContext的子类,而后者通过RequestContext和RouteData属性提供当前的请求上下文和路由数据(其实RouteData属性表示的RouteData对象已经包含在RequestContext属性表示的RequestContext对象中)。
二、UrlHelper.Action V.S. HtmlHelper.ActionLink
UrlHelper和HtmlHelper分别通过Action和ActionLink方法用于生成一个针对某个Controller的某个Action的URL和链接。下面的代码片断列出了UrlHelper的所有Action重载,参数actionName和controllerName分别代表Action和Controller的名称。通过object或者RouteValueDictionary类型表示的routeValues参数表示替换URL模板中变量的变量值。参数protocol和hostName代表作为完整URL的传输协议(比如http和https等)以及主机名。
1: public class UrlHelper
2: {
3: //其他成员
4: public string Action(string actionName);
5: public string Action(string actionName, object routeValues);
6: public string Action(string actionName, string controllerName);
7: public string Action(string actionName, RouteValueDictionary routeValues);
8: public string Action(string actionName, string controllerName, object routeValues);
9: public string Action(string actionName, string controllerName, RouteValueDictionary routeValues);
10:
11: public string Action(string actionName, string controllerName, object routeValues, string protocol);
12: public string Action(string actionName, string controllerName, RouteValueDictionary routeValues, string protocol, string hostName);
13: }
对于定义在UrlHelper中的众多Action方法,如果我们显示指定了传输协议(protocol参数)或者主机名称,返回的是一个完整的URL;否则返回的是一个相对URL。如果我们没有显示地指定Controller的名称(controllerName参数),那么当前Controller的名称被采用。对于UrlHelper来说,通过RequestContext属性表示的当前请求上下文包含了相应的路由信息,即RequestContext的RouteData属性表示的RouteData。RouteData的Values属性中必须包含一个Key为“controller”的元素,其值就代表当前Controller的名称。
在System.Web.Mvc.Html.LinkExtensions中,我们为HtmlHelper定义了如下所示的一系列ActionLink方法重载。顾名思义,ActionLink不再仅仅返回一个URL,而是生成一个链接(<a>...</a>),但是其中作为目标URL的生成逻辑和UriHelper是完全一致的。
1: public static class LinkExtensions
2: {
3: //其他成员
4: public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName);
5: public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues);
6: public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName);
7: public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues);
8: public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes);
9: public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes);
10: public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes);
11: public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName,RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes);
12: public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, object routeValues, object htmlAttributes);
13: public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string con
补充:Web开发 , ASP.Net ,