C# ActionLink、Html.BeginForm、Url.Content如何匹配正确的路径

C# ActionLink、Html.BeginForm、Url.Content如何匹配正确的路径,c#,asp.net,asp.net-mvc-3,asp.net-mvc-routing,url-routing,C#,Asp.net,Asp.net Mvc 3,Asp.net Mvc Routing,Url Routing,有人能给我解释一下,ActionLink(通常是Html助手)从哪里获得了正确的路径,以及它是如何创建正确的路径的。例如: 对于这样的路线 routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id =

有人能给我解释一下,ActionLink(通常是Html助手)从哪里获得了正确的路径,以及它是如何创建正确的路径的。例如:

对于这样的路线

routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );
actionlink看起来像:

@Html.ActionLink("MyCoolLink","About","Home")
<a href="/Home/About">About</a>
生成的HTML如下所示:

@Html.ActionLink("MyCoolLink","About","Home")
<a href="/Home/About">About</a>

谢谢大家!

ActionLink将使用默认路由或第一个匹配路由生成方法的虚拟路径。因此,您有以下选项

1在
Global.asax
registerOutes
中以更高的优先级添加条目(即在其他路线定义之前):

在这种情况下,
CustomRoute
将应用于所有匹配的路由,因此这是一个非常全局性的变化

2添加优先级较低的
CustomRoute
(即在其他路由之后),并在视图中以其为目标:

@Html.RouteLink("MyLink", "CustomRoute", new { controller = "Home", action = "Index" });
3将您自己的扩展方法写入HtmlHelper,以提供所需的功能。使用以下代码在解决方案中添加新文件:

namespace System.Web.Mvc {
{
    public static class HtmlHelperExtensions
    {
        public static MvcHtmlString CustomActionLink(this HtmlHelper htmlHelper, tring linkText, string actionName, string controllerName)
        {
            return new MvcHtmlString(String.Format("<a href='http://myUrl.com/{0}/{1}'>{2}</a>", controllerName, actionName, linkText));
        }
    }
}

4不要使用ActionLink helper的方法,只需在视图中写入您的URL。

URL.Content
:在内部,使用
URL.Content
时使用

而且,
Html.ActionLink
(以及
Url.RouteUrl
)使用方法。
ActionLink
实际上是特定于MVC(操作和控制器参数)和
Url的。RouteUrl
更具通用性

微软已经建立了
ActionLink
方法作为扩展方法。如果这些扩展仍然不符合您的目的,我们鼓励您编写自己的扩展

从下载源代码以查看Microsoft如何实现这些扩展

另外,让我们以一个创建自定义
HtmlHelper
方法的示例结束。 当创建自定义
HtmlHelper
方法时,下面的名称空间/类很好阅读

System.Web.Mvc.Html Namespace
System.Web.Mvc.TagBuilder Class
System.Web.Mvc.ModelMetaData Class
System.Web.Mvc.ExpressionHelper Class
System.Linq.Expressions.Expression<TDelegate> Class
要开始此操作,请创建一个名为
HtmlHelper
的静态类。让我们创建一个名为
ActionLinkWithSpan
的扩展方法,该方法将扩展
HtmlHelper

namespace Tutorial.Examples
{
using System;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

public static class HtmlExtensions
{
public static MvcHtmlString ActionLinkWithSpan(this HtmlHelper html,
string linkText,
string actionName,
string controllerName,
object htmlAttributes)
{
RouteValueDictionary attributes = new RouteValueDictionary(htmlAttributes);
TagBuilder linkTag = new TagBuilder("a");
TagBuilder spanTag = new TagBuilder("span");
spanTag.SetInnerText(linkText);

// Merge Attributes on the Tag you wish the htmlAttributes to be rendered on.
// e.g. linkTag.MergeAttributes(attributes);
spanTag.MergeAttributes(attributes);

UrlHelper url = new UrlHelper(html.ViewContext.RequestContext);
linkTag.Attributes.Add("href", url.Action(actionName, controllerName));
linkTag.InnerHtml = spanTag.ToString(TagRenderMode.Normal);
return MvcHtmlString.Create(linkTag.ToString(TagRenderMode.Normal));
}
}
}

建议您深入了解如何创建自定义MVC方法。

这里有一个关于MVC路由的基本解释:。和。。你想对你的路线做些什么?谢谢你的链接。问题更深,我在这里描述了其中的一部分,谢谢你的回答。您的解决方案很有趣,但实际上我希望避免重新生成所有MVC3帮助程序。问题不仅在于ActionLink,还在于所有Html助手。我想一定有一种方法可以在自定义路由处理程序中或在更高级别上实现这一点。但是我不知道在哪里,怎么。。谢谢大家!@Christian我的理解是ActionLink将使用路由表中的第一个匹配定义解析路由。您可以尝试重新排序管线定义,以获得所需的效果。您也可以尝试使用Html.RouteLink来定位特定的路由定义。如果我将Global.asax.cs中的路由映射到一个从route继承的自定义路由器类。请你给我解释一下在哪里,以及在哪里。我应该如何实现负责将路由与路径匹配的部分。非常感谢。@Christian我编辑了答案,以展示如何编辑路线。非常感谢您的回答,您为我指出了正确的来源。我会继续挖掘,然后带着完整的答案回来。
<a href="[action-link]"><span>[action-link text]</span></a>
namespace Tutorial.Examples
{
using System;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

public static class HtmlExtensions
{
public static MvcHtmlString ActionLinkWithSpan(this HtmlHelper html,
string linkText,
string actionName,
string controllerName,
object htmlAttributes)
{
RouteValueDictionary attributes = new RouteValueDictionary(htmlAttributes);
TagBuilder linkTag = new TagBuilder("a");
TagBuilder spanTag = new TagBuilder("span");
spanTag.SetInnerText(linkText);

// Merge Attributes on the Tag you wish the htmlAttributes to be rendered on.
// e.g. linkTag.MergeAttributes(attributes);
spanTag.MergeAttributes(attributes);

UrlHelper url = new UrlHelper(html.ViewContext.RequestContext);
linkTag.Attributes.Add("href", url.Action(actionName, controllerName));
linkTag.InnerHtml = spanTag.ToString(TagRenderMode.Normal);
return MvcHtmlString.Create(linkTag.ToString(TagRenderMode.Normal));
}
}
}