当您查看操作链接的源代码时,您会发现
<%= Html.ActionLink("LinkText", "Action", "Controller")
将匹配
public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName) {
return ActionLink(htmlHelper, linkText, actionName, controllerName, new RouteValueDictionary(), new RouteValueDictionary());
}
到目前为止,这看起来很好,因为它正在创建一个新的路由值字典,所以它不会传递当前上下文中的值以添加到新链接中,这就是将发生的事情。
然而,在代码的深处生成URL时:
public static string GenerateUrl(string routeName, string actionName, string controllerName, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, bool includeImplicitMvcValues) {
if (routeCollection == null) {
throw new ArgumentNullException("routeCollection");
}
if (requestContext == null) {
throw new ArgumentNullException("requestContext");
}
RouteValueDictionary mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, requestContext.RouteData.Values, routeValues, includeImplicitMvcValues);
VirtualPathData vpd = routeCollection.GetVirtualPathForArea(requestContext, routeName, mergedRouteValues);
if (vpd == null) {
return null;
}
string modifiedUrl = PathHelpers.GenerateClientUrl(requestContext.HttpContext, vpd.VirtualPath);
return modifiedUrl;
}
您可以看到引用了requestContext对象,它可以访问routeData和routeCollections,其中将包含ID数据。在创建VirtualPathForArea时,以下行是ID值出现在URL中的位置:
internal static VirtualPathData GetVirtualPathForArea(this RouteCollection routes, RequestContext requestContext, string name, RouteValueDictionary values, out bool usingAreas) {
if (routes == null) {
throw new ArgumentNullException("routes");
}
if (!String.IsNullOrEmpty(name)) {
usingAreas = false;
return routes.GetVirtualPath(requestContext, name, values);
}
string targetArea = null;
if (values != null) {
object targetAreaRawValue;
if (values.TryGetValue("area", out targetAreaRawValue)) {
targetArea = targetAreaRawValue as string;
}
else {
if (requestContext != null) {
targetArea = AreaHelpers.GetAreaName(requestContext.RouteData);
}
}
}
RouteValueDictionary correctedValues = values;
RouteCollection filteredRoutes = FilterRouteCollectionByArea(routes, targetArea, out usingAreas);
if (usingAreas) {
correctedValues = new RouteValueDictionary(values);
correctedValues.Remove("area");
}
VirtualPathData vpd = filteredRoutes.GetVirtualPath(requestContext, correctedValues);
return vpd;
}
这行代码:
VirtualPathData vpd = filteredRoutes.GetVirtualPath(requestContext, correctedValues)
获取虚拟路径(即路由)并将其返回。因此,虚拟路径将为/Home/About/Flib
。
然后,当返回该虚拟路径时,下一行将使用它来设置操作链接的客户端URL:
string modifiedUrl = PathHelpers.GenerateClientUrl(requestContext.HttpContext, vpd.VirtualPath)
看起来 ActionLink 是使用区域的虚拟路径设置的,这个虚拟路径就是与默认路由匹配的路由。