有没有办法在使用 Asp.Net MVC ActionLink、RedirectToAction 等时包含片段标识符?

Posted

技术标签:

【中文标题】有没有办法在使用 Asp.Net MVC ActionLink、RedirectToAction 等时包含片段标识符?【英文标题】:Is there a way to include a fragment identifier when using Asp.Net MVC ActionLink, RedirectToAction, etc.? 【发布时间】:2010-09-05 13:25:11 【问题描述】:

我希望一些链接包含片段标识符。喜欢这个网站上的一些网址:

Debugging: IE6 + SSL + AJAX + post form = 404 error#5626

有没有办法使用 MVC 中的任何内置方法来做到这一点?还是我必须推出自己的 html 助手?

【问题讨论】:

【参考方案1】:

正如 Brad Wilson 所写,您可以通过简单地连接字符串来在视图中构建自己的链接。但是要将片段名称附加到通过 RedirectToAction (或类似的)生成的重定向中,您需要这样的东西:

public class RedirectToRouteResultEx : RedirectToRouteResult 

    public RedirectToRouteResultEx(RouteValueDictionary values)
        : base(values) 
    

    public RedirectToRouteResultEx(string routeName, RouteValueDictionary values)
        : base(routeName, values) 
    

    public override void ExecuteResult(ControllerContext context) 
        var destination = new StringBuilder();

        var helper = new UrlHelper(context.RequestContext);
        destination.Append(helper.RouteUrl(RouteName, RouteValues));

        //Add href fragment if set
        if (!string.IsNullOrEmpty(Fragment)) 
            destination.AppendFormat("#0", Fragment);
        

        context.HttpContext.Response.Redirect(destination.ToString(), false);
    

    public string Fragment  get; set; 


public static class RedirectToRouteResultExtensions 
    public static RedirectToRouteResultEx AddFragment(this RedirectToRouteResult result, string fragment) 
        return new RedirectToRouteResultEx(result.RouteName, result.RouteValues) 
            Fragment = fragment
        ;
    

然后,在你的控制器中,你会调用:

return RedirectToAction("MyAction", "MyController")
       .AddFragment("fragment-name");

这应该会正确生成 URL。

【讨论】:

这很棒。在 MVC3 中,ActionLink 有一个重载,可以让你做一个片段,但不是 RedirectToAction【参考方案2】:

我们正在考虑在下一个版本中加入对此的支持。

【讨论】:

这是要在 dev10 中发布吗?【参考方案3】:

在 MVC3 中(可能之前我还没有检查过),您可以使用 UrlHelper.GenerateUrl 传入片段参数。这是我用来包装功能的辅助方法L

public static string Action(this UrlHelper url, string actionName, string controllerName, string fragment, object routeValues)

    return UrlHelper.GenerateUrl(
        routeName: null,
        actionName: actionName,
        controllerName: controllerName,
        routeValues: new System.Web.Routing.RouteValueDictionary(routeValues),
        fragment: fragment,
        protocol: null,
        hostName: null,
        routeCollection: url.RouteCollection,
        requestContext: url.RequestContext,
        includeImplicitMvcValues: true /*helps fill in the nulls above*/
    );

【讨论】:

有点尴尬,但这是这里最好的答案。也许,其他的只是过时了。【参考方案4】:

@Dominic,

我几乎可以肯定,将它放在路由中会导致路由问题。

@瑞奇,

在 MVC 对此提供支持之前,您可以更“老派”地了解如何制定路线。例如,您可以转换:

<%= Html.ActionLink("Home", "Index") %>

进入:

<a href='<%= Url.Action("Index") %>#2345'>Home</a>

或者您可以编写自己的助手来完成基本相同的操作。

【讨论】:

我用 ASP.NET MVC Preview 3 尝试了路由中的目标,路由没有问题。因此,尽管您“几乎是肯定的”,但详细说明会出现什么问题对您很有用。【参考方案5】:

简短的回答是:不。在 ASP.NET MVC Preview 3 中,没有一流的方法可以将锚点包含在操作链接中。与 Rails 的 url_for :anchor 不同,UrlHelper.GenerateUrl(以及使用它的 ActionLink、RedirectToAction 等)没有可以让您对锚进行编码的神奇属性名称。

正如您所指出的,您可以自行推出。这可能是最干净的解决方案。

Hackily,您可以在路由中包含一个锚点并在您的参数哈希中指定值:

routes.MapRoute("WithTarget", "controller/action/id#target");
...
<%= Html.ActionLink("Home", "Index", new  target = "foo" )%>

这将生成一个类似 /Home/Index/#foo 的 URL。不幸的是,这不适用于出现在 URL 末尾的 URL 参数。因此,这种 hack 仅适用于所有参数都显示为 URL 路径组件的非常简单的情况。

【讨论】:

【参考方案6】:

这是一个客户端解决方案,但如果你有可用的 jquery,你可以这样做。

<script language="javascript" type="text/javascript">
    $(function () 
        $('div.imageHolder > a').each(function () 
            $(this).attr('href', $(this).attr('href') + '#tab-works');
        );
    );
</script>

【讨论】:

【参考方案7】:

MVC 5 支持片段标识符。请参阅ActionLink 的重载https://msdn.microsoft.com/en-us/library/dd460522(v=vs.118).aspx 和https://msdn.microsoft.com/en-us/library/dd492938(v=vs.118).aspx。

【讨论】:

以上是关于有没有办法在使用 Asp.Net MVC ActionLink、RedirectToAction 等时包含片段标识符?的主要内容,如果未能解决你的问题,请参考以下文章

在 MVC 之外使用 ASP.Net MVC 数据注释

玩转Asp.net MVC 的八个扩展点

有没有办法将复选框列表绑定到 asp.net mvc 中的模型

如何在 ASP.Net MVC 中执行 301 永久重定向路由

Asp.net MVC:上传多个图像文件?

ASP.NET MVC 5使用Filter过滤Action参数防止sql注入