Pergunta

Um problema que enfrento repetidamente é lidar com o redirecionamento para a página anterior depois que um usuário executa alguma ação, como clicar no link 'Voltar para ...' ou salvar o registro que está editando.

Anteriormente, sempre que eu precisava saber para qual página retornar, eu fornecia um returnURL parâmetro para minha visualização atual.

http://blah.com/account/edit/1?returnURL="account/index"

Esta não é uma maneira muito limpa de lidar com esta situação, pois às vezes a URL de retorno contém parâmetros como strings de pesquisa, etc., que devem ser incluídos na URL.

http://blah.com/account/edit/1?returnURL="account/index?search="searchTerm""

Além disso, isso cria um problema quando um usuário pode avançar outra página antes de voltar para a página com o returnURL porque você tem que passar returnURL através de todas as páginas visitadas.

Simplesmente chamar a funcionalidade Voltar do navegador também não é suficiente, porque você pode querer que a página seja atualizada, por exemplo.para mostrar as edições que você acabou de salvar na página anterior.

Então, minha pergunta é: alguém encontrou uma maneira inteligente de lidar com esse tipo de situação, especificamente em um ambiente MVC?

Observação:Estou usando o ASP .NET MVC, então, se possível, gostaria de respostas relacionadas a isso, mas qualquer ideia é bem-vinda.

Foi útil?

Solução

O que há de errado em definir um cookie ou usar uma variável de sessão?A única razão pela qual você não faria isso é se você não controlar a página que chama para você, caso em que suas únicas opções são strings de consulta, valores de postagem ou referenciador.

Outras dicas

Pensei em adicionar minha resposta à pergunta para ver se outras pessoas acham que é uma boa ideia.

Estou simplesmente passando para o controlador usando TempViewData:

@{
   TempData["returnURL"] = Request.Url.AbsoluteUri;
}

e então acessá-lo de forma semelhante a esta (na minha versão real eu verifico se a chave está em TempData e que o returnURL é um URL real):

return Redirect(TempData["returnURL"].ToString());

Se precisar continuar após a primeira mudança de página (ou seja,Página de pesquisa -> Editar página -> Editar página de seção) Estou adicionando novamente

TempData["returnURL"] = TempData["returnURL"];

Verifique minha postagem do blog sobre isso: Usandocookies para controlar a página de retorno após o login em asp.net mvc 3

Assim como @Mystere Man mencionou, você pode apenas usar um cookie ou uma sessão para ele.Eu fui comprar cookies quando tive uma situação semelhante, há algum tempo.

Tente registrar uma nova rota da qual o url é /{controller}/{action}/{id}/returnurl/{*url} e, em seguida, use um RedirectToAction na ação que aceita url como parâmetro

Request.UrlReferrer.AbsoluteUri

embora eu ainda argumente que você não deveria criar seu próprio botão "voltar".

Use um interceptor ou um aspecto:

    .
  1. interceptar cada pedido de alguma forma (por exemplo, um aspecto generacodetagcode) e salvar o URL solicitado à sessão, sobrescrevê-lo a cada vez
  2. Na sua camada de exibição, acesse esse objeto de sessão conforme necessário, no seu caso para o link traseiro.

    Este tipo de design permite que você sempre tenha a solicitação mais recente disponível se você quiser usá-lo. Aqui está umExemplo Para escrever um aspecto / interceptor no .NET.Adicional, postsharp é um projeto de aspecto .NET.

Atualmente, um método rápido e sujo me escapou...então estou usando um método prático.

Em um nível conceitual, a capacidade de retrocesso de uma página deve ser determinada pela página em que você está atualmente.A View pode inferir isso (na maioria dos casos) se os parâmetros capturados no Controller forem passados ​​para ela através do ViewModel.

Exemplo:

Tendo visitado Foo, Eu vou Bar para ver algumas coisas, e o botão Voltar deve retornar para Foo.

Controlador

public ActionResult Foo(string fooId) // using a string for your Id, good idea; Encryption, even better.
{
    FooModel model = new FooModel() { fooId = fooId }; // property is passed to the Model - important.
    model.Fill();
    return View("FooView", model);
}

public ActionResult Bar(string fooId, string barId)
{
    BarModel model = new BarModel() { fooId = fooId; barId = barId };
    model.Fill()
    return View("BarView", model)
}

VerModelos

public class FooModel
{
    public string fooId { get; set; }

    public void Fill()
    {
        // Get info from Repository.
    }
}

public class BarModel
{
    public string fooId { get; set; }
    public string barId { get; set; }

    public void Fill()
    {
        // Get info from Repository.
    }
}

Visualizar (parcial) // No pun intended... or maybe it was. :)

Seu BarView agora pode interpretar a partir de seu modelo para onde ele precisa voltar (usando fooId).

No seu BarView (usando a sintaxe MVC2):

<a href="<%= string.Format("/Foo?fooId={0}", Model.fooId) %>">Back</a>

Você também pode usar Html.ActionLink.

Alternativamente:

Você pode herdar seus ViewModels de um BaseViewModel, que pode ter uma propriedade protegida returnURL.Defina isso quando necessário.

Exemplo:

No seu ViewModel:

public class BarModel : BaseViewModel
{
    public string fooId { get; set; }
    public string barId { get; set; }

    public void Fill()
    {
        returnURL = string.Format("/Foo?fooId={0}", fooId)
        // Get info from Repository.
    }
}

Em Exibiçao:

<a href="<%=returnURL %>">Back</a>

Isso seria melhor tratado por ações parciais que são exibidas sem sair da página e usando JQuery para fazer um fluxo de trabalho de diálogo / assistente?

Então você só precisa reagir ao botão 'Concluir' na caixa de diálogo para atualizar a visualização original.

Para a parte da sua pergunta sobre "salvar o registro que eles estão editando", acho que o padrão post-redirect-get (PGR) se aplica a você.

Este pode ser um bom lugar para ler sobre isso, se você não estiver familiarizado com ele.

  1. Codifique o returnUrl usando Url.Encode(returnUrl) para inclusão no URL.
  2. Quando estiver pronto para redirecionar, use Url.Decode(returnUrl) e use o valor para o redirecionamento real.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top