使用Asp.Net MVC ActionLink,RedirectToAction等时,是否可以包含片段标识符?

时间:2020-03-05 18:38:32  来源:igfitidea点击:

我希望某些链接包含片段标识符。像此网站上的某些URL:

调试:IE6 + SSL + AJAX +发布表单= 404错误#5626

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

解决方案

回答

简短的答案是:否。在ASP.NET MVC Preview 3中,没有一流的方法可以在动作链接中包含锚点。与Rails的url_for:anchor不同,UrlHelper.GenerateUrl(以及ActionLink,RedirectToAction等使用它)没有魔术属性名称,可用于编码锚点。

如我们所指出的,我们可以自己动手做。这可能是最干净的解决方案。

顺便说一句,我们可以在路线中添加锚点,然后在参数哈希中指定值:

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

这将生成一个类似于/ Home / Index /#foo的URL。不幸的是,这不能与URL参数一起使用,URL参数显示在URL的末尾。因此,只有在所有参数都显示为URL路径组件的非常简单的情况下,此技巧才可行。

回答

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

回答

@Dominic,

我几乎肯定地说,将其放入路由会导致路由问题。

@Ricky,

在MVC对此提供支持之前,我们可以对路线的设置有更多的了解。例如,我们可以转换:

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

进入:

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

或者,我们可以编写自己的帮助程序,而该帮助程序基本上可以完成相同的操作。

回答

正如布拉德·威尔逊(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。