Pergunta

O site que estou trabalhando tem algumas estruturas de roteamento bastante complicado e estamos passando por algumas dificuldades que trabalham com o mecanismo de roteamento para URLs construir a nossa forma de necessidade -los a ser construído.

Nós temos uma página de resultados de pesquisa que usa regex correspondência de padrão com base para agrupar várias variáveis ??em um segmento de rota única (ou seja, "www.host.com/{structuralParameters}" pode ser o seguinte: "www.host.com/variableA -variableB-variableC" - onde variáveis ??de A a C são todos opcionais). Isso está funcionando para nós fina, após um pouco de trabalho.

O problema que estamos enfrentando resolve em torno de uma característica irritante do método ActionLink: se você apontar para o mesmo controlador / ação que irá reter os valores rota existente se você quer ou não. Nós preferimos ter controle sobre o que os nossos laços olhar como e, em alguns casos, não podem ter os parâmetros existentes mantida. Um exemplo seria quando principais ligações de navegação do nosso site para uma página de resultados de pesquisa sem parâmetros set - uma página de pesquisa padrão, se você gosta. Digo isto é uma característica irritante porque é um raro exemplo do ASP.Net MVC Framework aparentemente ditando implementação sem um ponto de extensão óbvia - nós preferimos não criar código personalizado ActionLink para escrever um link de navegação simples na nossa página mestra

Eu vi alguns dizem que é necessário definir explicitamente tais parâmetros para ser strings vazias, mas quando tentamos isso, apenas muda os parâmetros de valores de rota em consulta parâmetros de cadeia. Isso não parece certo para mim que deveríamos ser obrigados a excluir explicitamente valores que não estão passando explicitamente como parâmetros para o método ActionLink mas se esta é a nossa única opção que vai usá-lo. No entanto, actualmente, se ele está exibindo na cadeia de consulta, então é inútil para nós como colocar os parâmetros diretamente para a rota.

Estou ciente de que a nossa estrutura de roteamento exaspera esse problema - nós provavelmente não teria qualquer problema se usamos uma abordagem mais simples (ou seja www.host.com/variableA/variableB/variableC), mas a nossa estrutura de URL não é negociável -. ele foi projetado para necessidades muito específicas atender relativos à usabilidade, SEO e link / compartilhamento de conteúdo

Como podemos usar Html.ActionLink para gerar links para páginas sem cair sobre os dados de rota atual (ou, se possível, precisando excluindo explicitamente segmentos de rota), mesmo se esses links levam a métodos mesma ação?

Se fizermos necessidade de excluir explicitamente segmentos de rota, como podemos impedir que o método de tornar as rotas como parâmetros cadeia de consulta?

Este aparentemente pequeno problema está nos causando uma surpreendente quantidade de dor e eu vou ser grato por qualquer ajuda em resolvê-lo.

EDIT: Conforme solicitado pela LukLed, aqui está um exemplo de chamada ActionLink:

// I've made it generic, but this should call the Search action of the 
// ItemController, the text and title attribute should say "Link Text" but there
// should be no parameters - or maybe just the defaults, depending on the route.
// 
// Assume that this can be called from *any* page but should not be influenced by
// the current route - some routes will be called from other sections with the same
// structure/parameters.
Html.ActionLink( 
    "Link Text",
    "Search", 
    "Item", 
    new { }, 
    new { title = "Link Text" } 
);
Foi útil?

Solução

Definir valores de rota a ser nulo ou string vazia ao chamar Html.ActionLink ou Html.RouteLink (ou qualquer método de geração de URL) irá limpar os "ambientes" valores de rota.

Por exemplo, com a rota controlador de MVC / ação / id padrão suponha que você está no "Home / Index / 123". Se você chamar Html.RouteLink(new { id = 456 }) então MVC vai notar os "ambientes" valores de rota de controller="Home" e action="Index". Ele também vai notar o valor rota ambiente de id="123" mas que irá obter substituído pelo "456" explícito. Isso fará com que a URL gerada para ser "/ Index Casa / 456".

A ordenação dos parâmetros importa também. Por exemplo, digamos que você chamou Html.RouteLink(new { action = "About" }). A ação "About" iria substituir a ação atual "Index", eo parâmetro "id" ficaria esvaziado inteiramente! Mas por que, você pergunta? Porque uma vez que você invalidar um segmento de parâmetro, em seguida, todos os segmentos parâmetro depois ele vai ficar invalidados. Neste caso, a "ação" foi invalidada por um novo valor explícito para que o "id", o que vem depois dela, e não tem nenhum valor explícito, também fica invalidada. Assim, a URL gerada seria apenas "Home / About" (sem um ID).

Neste mesmo cenário se você chamou Html.RouteLink(new { action = "" }) então a URL gerada seria apenas "Home" porque você invalidou o "ação" com uma cadeia vazia, e, em seguida, que causou o "id" para ser invalidado assim porque veio depois a "ação" invalidado.

Outras dicas

Solução na raiz do problema

Parece que a melhor solução (que não cheira como uma solução alternativa) é o que resolve o problema onde tem raízes e que está no roteamento.

Eu escrevi uma classe Route personalizado chamado RouteWithExclusions que é capaz de definir nomes de valor rota que devem ser excluídos / removidos ao gerar URLs. O problema é quando encaminhamento quedas através da tabela rotas e rotas subseqüentes não têm os mesmos nomes de valor de rota ...

O problema todo é detalhado e explicado em meu blog e todo o código é fornecido lá também. Check it out, pode ajudar a resolver este problema de roteamento. Eu também escrevi dois métodos de extensão MapRoute adicionais que levam um parâmetro adicional.

Se você quer controle total do link, basta construir o link-se:

<a href="~/variableA/variableB/<%= Html.Encode(Model.Target) %>">Click Here</a>

Substitua o que você precisa dentro do atributo href.

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