Asp.Net MVC Routing - como faço para coincidir com todo o URL?
-
06-07-2019 - |
Pergunta
Eu estou tentando criar um catch-all rota para controlar quando uma string da filial é na URL. Um código affilite é marcada por uma x
seguido por um int
, e só vai aparecer no final de uma URL (mas antes da string de consulta).
A idéia é que vou extrair o ID de afiliado, fazer alguma extração de madeira, em seguida, fazer um 301 com o mesmo pedido sem o ID de afiliado.
Por exemplo:
http://www.domain.com/x32
http://www.domain.com/x32/
http://www.domain.com/path/to/something/x32
http://www.domain.com/x32?query=string
http://www.domain.com/x32/?query=string
http://www.domain.com/path/to/something/x32?query=string
http://www.domain.com/path/to/something/x32/?query=string
Eu tenho essa rota ??p>
routes.Add(new Route("{url}/x{affiliateExternalId}", new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(
new { controller = "Home", action = "LogCookieAndRedirect" }
),
Constraints = new RouteValueDictionary(new { affiliateExternalId = @"\d{1,6}" })
});
O que só corresponde
http://www.domain.com/path/x32
http://www.domain.com/path/x32/
O que eu preciso fazer para combinar tudo e passar a string de consulta para o controlador? Há um operador *
que eu suspeito que eu deveria usar, mas eu não posso obtê-lo para fazer o que eu preciso.
Solução
{*url}
vai coincidir com o caminho todo ao invés de apenas um segmento. No entanto, uma vez que coincide todo o caminho, você não pode, em seguida, combinar com o ID de afiliado no final. O percurso irá corresponder a todos os pedidos. Você pode contornar isso adicionando uma restrição rota para verificar se url
tem um ID de afiliado no final:
routes.MapRoute(
"WithAffiliate",
"{*url}",
new { controller="Home", action="LogCookieAndRedirect" },
new { url = @"/x[0-9]+$" }
);
A sua acção terá então de analisar o ID de afiliado do url
próprio parâmetro. Se você tem a opção de modificar a estrutura de URL, seria possível combinar com o ID se fosse no início do caminho:
routes.MapRoute(
"WithAffiliate",
"x{affiliateExternalId}/{*url}",
new { controller="Home", action="LogCookieAndRedirect" }
);
Outras dicas
Se eu estivesse fazendo isso, gostaria de torná-lo um dos valores na cadeia de consulta.
Exemplo:
http//www.domain.com/path/to/something?affiliate=X32&query=string
O problema é que o ID de afiliado é opcional . Se você colocá-lo no caminho você vai mudar a estrutura do caminho com base em se ou não o ID de afiliado está presente, então você vai ter que fazer cada um de suas rotas duas vezes (uma vez com o ID de afiliado, e uma vez sem) .
Você só pode ter este catch-all rota se você tem apenas uma rota definida. Mas se você tem várias rotas, então você vai ter que adicionar esse parâmetro {affiliateExternalId}
a todas as rotas (a menos que eu estou faltando alguma coisa).
Eu segunda Robert Harvey 's sugestão .