Visualização 4 do ASP.NET MVC - Pare Url.RouteUrl() etc.usando parâmetros existentes

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

  •  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?

Foi útil?

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 })
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top