Conselhos para a construção de uma dinâmica “Pesquisa Avançada” Control no ASP.NET

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

Pergunta

alt texto http://img3.imageshack.us/img3/1488/advancedsearch. png

Eu estou construindo uma interface "Pesquisa Avançada" em um aplicativo ASP.NET. Eu não preciso de SO para escrever esta coisa para mim, mas eu estou preso em um problema específico em relação a controles dinâmicos e ViewState. Eu gostaria de alguma orientação para a forma de abordar isso. Aqui está a minha situação:

Ingredientes:

  • Um conjunto útil de objetos API representando entidades, campos e pesquisas, que lida com construção de uma pesquisa, gerando SQL, e retornando os resultados. Então, isso é tudo resolvido.
  • ASP.NET 3.5

desejado interface Funcionalidade:

(1) no carregamento da página inicial, a interface recebe um objeto de pesquisa pré-configurado com um conjunto de objetos SearchCriterion. Ele se liga-los em um conjunto de controles (ver imagem acima).

  • Alguns itens da pesquisa são mais simples, como:

    Field (DropDownList) | Operator (DropDownList) | Valor (TextBox)

  • controles critério de pesquisa para alguns tipos de campo têm dados importantes armazenados no estado de visualização, como:

    Field (DropDownList) | Operator (DropDownList) | Valor (DropDownList) onde o dropdownlist "Valor" é preenchida por uma consulta de banco de dados.

  • Alguns campos são as pesquisas a outras entidades, o que provoca uma cadeia de seletores de campo, como:

    Field (DropDownList) Field (DropDownList) | Operator (DropDownList) | Valor

(2) Os modifica usuários a busca por:

  • Adicionando e removendo critérios de pesquisa clicando respectivos botões
  • Configuração critérios mudando o campo, Operador ou valor existente. Mudanças a Campo ou operador exigirá o controle para si reconfigure alterando os operadores disponíveis, mudando o controle de entrada "Valor" para um tipo diferente, ou adicionar / remover DropDownLists da seção "Fields" se os campos de pesquisa do tipo são selecionados / desmarcada .

(3) Finalmente, os hits do usuário "Pesquisar" para ver os resultados.

O Problema:

Como você provavelmente já sabe, se você está respondendo a esta pergunta, os controles adicionados dinamicamente para a página de desaparecer no postback. Eu criei um UserControl que manipula a coleção de controle e ordenadamente realiza passo (1) acima, como você pode ver na imagem em anexo. (Eu não estou preocupado com estilo, neste ponto, obviamente.)

No entanto, em Postback, os controles são todos embora, e meu objeto Search API está desaparecido. Se eu pudesse obter a coleção de controle gerados dinamicamente para apenas bom jogo e vara em ViewState, pude examinar os controles na postagem, reconstruir o objeto de pesquisa, em seguida, manipular eventos de controle ordenadamente.

Possíveis soluções

  • Eu poderia fazer a pesquisa objeto serializado e armazená-lo em estado de visualização. Em seguida, no carregamento da página eu pudesse agarrá-lo e reconstruir a coleção de controle em tempo de carregamento da página. No entanto, eu não tenho certeza se isso iria jogar bem com controles elevar eventos, eo que acontece com o estado de visualização de listas que contêm dados do banco de dados suspensa - eu poderia obtê-lo de volta? É altamente indesejável para mim ter que re-consulta o banco de dados em cada nova postagem.

  • Eu poderia desenvolver um controle de servidor personalizado ( veja este link ) para este tipo de coisa ... mas isso é um tema novo para mim e envolveria algum aprendizado, mais eu não estou totalmente certo se um controle de servidor personalizado iria trabalhar mais bem com coleções não-fixos de controle. Alguém sabe sobre isso?

  • Eu estava pensando que eu poderia ser capaz de fazer isso usando controles de ligação de dados - por exemplo, eu poderia vincular minha coleção critério para um repetidor, que tem uma coleção de controle fixo (talvez ocultar os controles de "valor" não-utilizados, usar um innerepetidor r para as listas drop-down "campo"). Em seguida, todas as informações ficaria em ViewState ... certo?

  • As novas ideias seria muito apreciada.

obrigado pela sua ajuda. b.Fandango

Foi útil?

Solução

Eu tenho de codificação por cerca de um dia e eu tenho esta trabalhando muito bem usando a terceira opção sugeri na minha pergunta - controles de ligação de dados da velha escola. Na verdade, eu só pensava da ideia quando eu fui forçado a escrever a questão em detalhe -? Não que só acontecerá a você o tempo todo

Eu coloquei minha SearchCriterionControl em um asp: Repeater e ligou-o a minha coleção de objetos. Para o Selector de campos Coloquei um asp: DropDownList dentro de um asp aninhada: Repeater e obrigado a matriz de campo para isso. Tudo funciona muito bem, mantém estado, código muito pouco realmente necessário. Então eu nunca tive que adicionar dinamicamente controles para a página, graças a Deus.

Obrigado por suas sugestões, Ender, Matt e AndrewWinn.

Outras dicas

Uma vez que ninguém tomou uma facada isso por 2 horas, eu vou jogar meu chapéu no anel com uma solução que não depende de viewstate em tudo (ou o modelo ASP.NET de postbacks).

E se você pegou todos os valores de entrada com jQuery e em vez de fazer um post-back fiz um post contra a página (ou uma nova página results.aspx)? Ou, você pode fazer todo o modo assíncrono coisa e fazer uma solicitação do Ajax contra um método web, se alimentou os resultados, e preencher no lado do cliente, conforme necessário?

A coisa infeliz aqui é que você tem que reconstruir qual o tipo de controles foram usadas para figura construir a sua consulta de pesquisa, uma vez que os dados não vai ser passado com o viewstate. Mas imagino que você já foram vai ter que fazer algum tipo de tradução dos seus dados de entrada em um formulário de consulta de qualquer maneira.

Leia aqui para obter mais informações sobre como usar jQuery para bater um método de página ASP.NET. Lembre-se -. Métodos de página deve ser estático (é um descuido fácil)

Eu não tenho certeza do que está fazendo do lado do servidor para construir sua consulta - mas eu altamente recomendar LINQ. Eu fiz uma função semelhante "pesquisa avançada" anteriormente, e depois de algumas tentativas diferentes descobriu que LINQ foi uma ferramenta maravilhosa para este problema, independentemente de eu estava batendo SQL com LINQtoSQL ou apenas bater uma coleção na memória de objetos.

Isso funcionou tão bem porque 1) LINQ é adiada execução e 2) consulta A LINQ retorna outro objeto queryable. A implicação aqui é que você pode encadear suas consultas LINQ juntos, como você construí-los a partir de sua entrada, em vez de ter que fazer uma única tradução maciça cláusula de SQL ou qualquer backstore você está usando (uma das minhas tentativas foi a construção de cláusulas SQL com cordas, mas ainda passando dados de entrada via SqlParameters para proteção de injeção SQL -. era confuso e complicado quando artesanal LINQ foi ordens de magnitude mais fácil de compreender e aplicar)

Por exemplo:

List<string> data; // or perhaps your a DB Context for LINQtoSQL?

var query = data.Where(item => item.contains("foo"));

if( {user supplies length search option} )
    query = query.Where(item => item.Length < 5);

// etc, etc.

// LINQ doesn't do anything until the query is iterated, at which point
// it will construct the SQL statement without you worrying about details or parameter binding
foreach(string value in query)
    ; // do something with the results

Por causa da execução adiada eo tipo queryable troca, você pode concatenar consultas LINQ para esta expressão durante todo o dia e deixá-lo se preocupar com os detalhes de implementação (tais como a conversão para uma consulta SQL) em tempo de execução.

Eu não posso fornecer-lhe as etapas exatas que você precisa fazer, mas eu sugiro olhar em ciclo asp.net página vida. Eu criei um controle de usuário como um DLL uma vez. Eu tinha de dados de postagem de captura em etapas específicas do ciclo de vida e recriar e religar os dados em outras etapas. Além disso thinkgs como viewstate estão disponíveis apenas em determinados pontos também. Eu sei que eu tive que substituir On_init, On_prerender e alguns outros métodos.

Desculpe eu não poderia estar mais ajuda, mas eu não tenho o código comigo (o seu com um empregador de idade). Espero que isso ajude.

Se você estiver adicionando controles para a árvore de controles dinamicamente, é necessário adicioná-los postpack também. Basta ligar para o método que constrói o controle sobre Page_Load ou Page_Init e os controles devem permanecer na página de postagem.

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