Existe uma maneira de incluir um identificador de fragmento ao usar Asp.Net MVC ActionLink, RedirectToAction, etc.?

StackOverflow https://stackoverflow.com/questions/5628

  •  08-06-2019
  •  | 
  •  

Pergunta

Quero que alguns links incluam um identificador de fragmento.Como alguns dos URLs deste site:

Depuração:IE6 + SSL + AJAX + formulário de postagem = erro 404#5626

Existe uma maneira de fazer isso com algum dos métodos internos do MVC?Ou eu teria que lançar meus próprios ajudantes HTML?

Foi útil?

Solução

Estamos pensando em incluir suporte para isso em nosso próximo lançamento.

Outras dicas

Como escreveu Brad Wilson, você pode construir seu próprio link em suas visualizações simplesmente concatenando strings.Mas para anexar um nome de fragmento a um redirecionamento gerado via RedirectToAction (ou similar), você precisará de algo assim:

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
        };
    }
}

E então, no seu controlador, você chamaria:

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

Isso deve gerar o URL corretamente.

No MVC3 (e possivelmente antes que não verifiquei), você pode usar UrlHelper.GenerateUrl passando o parâmetro fragmento.Aqui está um método auxiliar que uso para agrupar a funcionalidade

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*/
    );
}

@Dominic,

Tenho quase certeza de que colocar isso na rota causará problemas de roteamento.

@Ricky,

Até que o MVC tenha suporte para isso, você pode ser um pouco mais “old school” em como faz suas rotas.Por exemplo, você pode converter:

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

em:

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

Ou você pode escrever seu próprio auxiliar que faz essencialmente a mesma coisa.

A resposta curta é:Não.No ASP.NET MVC Preview 3 não há uma maneira excelente de incluir uma âncora em um link de ação.Ao contrário do url_for :anchor do Rails, UrlHelper.GenerateUrl (e ActionLink, RedirectToAction e assim por diante que o utilizam) não possui um nome de propriedade mágica que permite codificar uma âncora.

Como você apontou, você poderia criar o seu próprio.Esta é provavelmente a solução mais limpa.

Hackily, você poderia simplesmente incluir uma âncora em uma rota e especificar o valor no hash de seus parâmetros:

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

Isso irá gerar uma URL como /Home/Index/#foo.Infelizmente, isso não funciona bem com os parâmetros de URL, que aparecem no final do URL.Portanto, esse hack só funciona em circunstâncias realmente simples, onde todos os seus parâmetros aparecem como componentes de caminho de URL.

Esta é uma solução do lado do cliente, mas se você tiver o jquery disponível, poderá fazer algo assim.

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

Identificadores de fragmento são suportados no MVC 5.Ver ActionLinksobrecargas em https://msdn.microsoft.com/en-us/library/dd460522(v=vs.118).aspx e https://msdn.microsoft.com/en-us/library/dd492938(v=vs.118).aspx.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top