Visualização 4 do ASP.NET MVC - Pare Url.RouteUrl() etc.usando parâmetros existentes
-
09-06-2019 - |
Pergunta
Eu tenho uma ação como esta:
public class News : System.Web.Mvc.Controller
{
public ActionResult Archive(int year)
{
/ *** /
}
}
Com um percurso como este:
routes.MapRoute(
"News-Archive",
"News.mvc/Archive/{year}",
new { controller = "News", action = "Archive" }
);
A URL em que estou é:
News.mvc/Archive/2008
Eu tenho um formulário nesta página como este:
<form>
<select name="year">
<option value="2007">2007</option>
</select>
</form>
O envio do formulário deve ir para News.mvc/Archive/2007 se '2007' estiver selecionado no formulário.
Isso requer que o atributo 'action' do formulário seja "News.mvc/Archive".
No entanto, se eu declarar um formulário como este:
<form method="get" action="<%=Url.RouteUrl("News-Archive")%>">
ele é renderizado como:
<form method="get" action="/News.mvc/Archive/2008">
Alguém pode me informar o que estou perdendo?
Solução
Você tem alguns problemas, eu acho.
Primeiro, sua rota não possui um valor padrão para "ano", portanto a URL "/News.mvc/Archive" não é válida para fins de roteamento.
Segundo, você espera que os valores do formulário apareçam como parâmetros de rota, mas não é assim que o HTML funciona.Se você usar um formulário simples com seleção e envio, seus URLs terão "?year=2007" no final deles.É assim que os formulários do método GET são projetados para funcionar em HTML.
Então você precisa chegar a alguma conclusão sobre o que é importante.
- Se você deseja que o usuário possa selecionar algo no menu suspenso e isso altera o URL de envio, você terá que usar Javascript para conseguir isso (interceptando o envio do formulário e formulando o URL correto).
- Se você concorda com /News.mvc/Archive?year=2007 como seu URL, remova totalmente o designador {year} da rota.Você ainda pode deixar o parâmetro "int year" na sua ação, já que os valores do formulário também preencherão os parâmetros do método de ação.
Outras dicas
Acho que descobri o porquê - a rota inclui {year}, então as rotas geradas sempre incluirão.
Se alguém puder confirmar isso?
Solução
Ok, aqui está a solução (obrigado ao Brad por me guiar até lá).
1) Exigir valor padrão na rota:
routes.MapRoute(
"News-Archive",
"News.mvc/Archive/{year}",
new { controller = "News", action = "Archive", year = 0 }
);
2) Adicione um redirecionamento para analisar os parâmetros GET como se fossem segmentos de URL.
public ActionResult Archive(int year)
{
if (!String.IsNullOrEmpty(Request["year"]))
{
return RedirectToAction("Archive", new { year = Request["year"] });
}
}
3) Certifique-se de ter seu código de redirecionamento para parâmetros de solicitação antes qualquer código para redirecionar entradas de ano "padrão".ou seja
public ActionResult Archive(int year)
{
if (!String.IsNullOrEmpty(Request["year"]))
{
return RedirectToAction("Archive", new { year = Request["year"] });
}
if (year == 0)
{
/* ... */
}
/* ... */
}
3) Especifique explicitamente o valor padrão para ano na chamada Url.RouteUrl():
Url.RouteUrl("News-Archive", new { year = 0 })