Pergunta

A minha falta de familiaridade com o framework ASP.NET MVC eo encanamento do mesmo me trouxe aqui, e eu aprecio a paciência vai demorar para que todos possam ler e considerar a minha pergunta!

Ok, aqui é o cenário: Eu tenho um aplicativo que tem inúmeras páginas com grades que os dados de exibição com base em pesquisas, perfuração para baixo a partir de outros dados, relatórios com base em dados específicos ao contexto (ou seja, eles estão em uma página de detalhes para Foo , em seguida, clique em um link que mostra uma tabela de dados relacionadas com Foo), etc.

A partir de qualquer e todas estas páginas, que são em todo o aplicativo, o usuário pode salvar o "relatório" ou grade, dando-lhe um nome e uma descrição. Este realmente não guardar os dados exibidos na grade, tanto como guarda os parâmetros que definem o que os olhares grade como, guarda os parâmetros que foram utilizados para get os dados e salva os parâmetros que definem "onde" no aplicativo são (a ação, controlador, route) -. basicamente um conjunto de metadados sobre o relatório / grade e como construí-lo

Todos estes relatórios salvos estão disponíveis em uma única lista, exibindo o nome e descrição, em uma determinada página no aplicativo, com cada um link para uma URL genérica, como "/ Reports / Saved / 248" (onde 248 é um exemplo de ID do relatório).

Aqui é a parte que eu preciso de ajuda em:

Quando eu chegar ao ação através da url "/ Reports / Saved / 248" e puxar os metadados do banco de dados para esse relatório específico, como posso redirecionar esses dados e o pedido para a mesma ação, controlador e rota usado para exibir a visão de que o relatório foi originalmente salvo de? Essencialmente, eu quero o usuário para ver o relatório na mesma vista, com o mesmo URL como ele foi salvo da. Se possível, seria bom para mim ser capaz de, basicamente, "chamada" que mesma ação como se eu estivesse fazendo uma chamada de método.


UPDATE: Infelizmente, nossas páginas de relatório (ou seja, as páginas essas grades aparecem) não estiver usando URLs RESTful - por exemplo, temos o que chamamos de uma página de pesquisa avançada, o que leva um número bastante grande de parâmetros potenciais (quase 30 ) que vêm de um formulário contendo listas de seleção, caixas de texto, etc. Quando as submete usuário dessa página, nós fazemos um POST para uma ação que aceita um tipo complexo que o fichário de modelo constrói para nós - essa mesma ação é o que eu quero chamar quando o usuário seleciona uma Pesquisa avançada salvas no banco de dados. Esse exemplo resume o meu problema.

Graças

Foi útil?

Solução

Eu acho que você vai querer usar RedirectToAction com a assinatura que leva um RouteValueDictionary. O método que você está redirecionando a necessidade vontade de ser capaz de puxar os valores da ValueProvider no controlador. Pode parecer algo como:

public ActionResult Saved( int id )
{
    var reportParams = db.Reports.SingleOrDefault( r => r.ID == id );
    if (reportParams == null)
       ...handle error...

    var routeValues = ParamsToRouteValueDictionary( reportParams );

    return RedirectToAction( reportParams.Action, reportParams.Controller, routeValues );
}

private RouteValueDictionary ParamsToRouteValueDictionary( object parameters )
{
     var values = new RouteValueDictionary();
     var properties = parameters.GetType().GetProperties()
                                .Where( p => p.Name != "Action" && p.Name != "Controller" );
     foreach (var prop in properties)
     {
         values.Add( prop.Name, prop.GetValue(parameters,null) );
     }

     return values;
}

Editar

Usando um modelo de filtro como o parâmetro para o seu método realmente pode torná-lo mais fácil. Você só precisa GET e POST versões de sua ação.

 [ActionName("People")]
 [AcceptVerbs( HttpVerbs.Get )]
 public ActionResult PeopleDisplay( SearchModel filter )
 {
     return People( filter );
 }

 [AcceptVerbs( HttpVerbs.Post)]
 [ValidateAntiForgeryToken]
 public ActionResult People( SearchModel filter )
 {
     ....
 }

Então você teria que armazenar em seu banco de dados para o relatório dos parâmetros de filtro (por nome), a ação ( "Pessoas"), eo Controller. O resultado de redirecionamento vai usar GET e ser direcionado para o método PeopleDisplay, que por sua vez simplesmente chama o método de Pessoas com o parâmetro correto. Publicação do formulário chama o método As pessoas diretamente. Usando dois métodos permite que você use o mecanismo de prevenção de CSRF. Você pode ser capaz de usar uma bandeira em TempData para garantir que a ação GET só é invocado através do mecanismo de redirecionamento se o cuidado de restringir o acesso a ele.

EDIT END

Outra alternativa, seria a de simplesmente armazenar a exibição usado como bem e em vez de fazer um redirecionamento, apenas tornar a visão apropriada. Uma das coisas que você vai querer considerar é que fazer o redirecionamento vai acabar com uma URL que contém todos os parâmetros, enquanto tornando a vista vai deixar o URL sozinho e apenas exibir a mesma vista como o URL usado ao criar o relatório .

Outras dicas

Você pode usar o método RedirectToAction para emitir um redirecionamento 301 para um método de ação específica em qualquer controlador, juntamente com valores de rota:

ReportMeta meta = _reportDataAccess.Get(id);
return RedirectToAction(meta.Action, meta.Controller, meta.RouteData);

onde esses valores são algo como:

meta.Action = "Bar";
meta.Controller = "Foo";
meta.RouteData = new {
    // possibly settings for the grid
    start = DateTime.Min,
    end = DateTime.Now,
    sort = "Date"
    // you get the idea
};

É claro que a questão imediata que eu posso ver com isto é o que acontece quando o controlador de métodos / Acção mudar ao longo do tempo, os dados do relatório será inválido. Mas então você provavelmente pensou que já.

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