ASP.NET MVC - Getting Html.BeginForm () para lembrar parâmetros QueryString ao enviar via GET

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

  •  10-07-2019
  •  | 
  •  

Pergunta

Eu tenho um formulário prestados via Html.BeginForm (), ele existe como um componente na página mestra para que ele aparece em todas as páginas na aplicação. Eu fiz isso usando Html.RenderAction () de Mvc Futures montagem. É um formulário de pesquisa simples que atualiza alguns itens no mesmo componente underneigh o próprio formulário de busca e executa um GET para que o termo de pesquisa aparece na querystring.

<div class="sideBarContent">
   <h2>Search Products</h2>

   <% using (Html.BeginForm(ViewContext.RouteData.Values["action"].ToString(),
         ViewContext.RouteData.Values["controller"].ToString(), FormMethod.Get)) { %>

      <fieldset>
         <legend>Search Products</legend>

         <div class="formRow">
            <label for="ProductsSearch">Search</label>
            <%= Html.TextBox("ProductsSearch") %>
         </div>

         <input type="submit" value="Search" class="button" />
       </fieldset>

   <% } %>

   <ul>
      // Products will eventually be listed here
   </ul>
</div>

Eu preciso este formulário para fazer o seguinte:

1) Deve executar um GET para qualquer página atual é sobre anexando 'ProductsSearch' como um parâmetro querystring (ex. example.com/?ProductsSearch=test ou example.com / livros / ficção? ProductsSearch = test )

2) Deve-se lembrar quaisquer parâmetros querystring exising que já estão na querystring, mantendo-los depois que você clique em Procurar botão por exemplo. example.com/myOrders?page=2 após Pesquisa clique deve ir para example.com/myOrders?page=2&ProductsSearch=test )

Eu posso obtê-lo para fazer 1), mas não pode trabalhar fora 2).

Eu relise que normalmente por um a partir de obter e anexando parâmetros querystring ele precisa ter campos do formulário ocultos, para que eu pudesse escrever uma função de utilitário que automaticamente adiciona um monte de campos de formulários ocultos para quaisquer valores de querystring, mas eu queria verificar que há não era uma abordagem mais fácil, ou talvez eu estou indo pelo caminho errado.

Felicidades!

Foi útil?

Solução

Você precisa fazer o método de campo de formulário oculto.

Mesmo que você pode anexar toda a querystring para o final da URL no atributo da tag

ação, navegadores não prestar atenção a isso quando fazendo formulário GET submissões.

Seu método não é muito difícil; que você gostaria de fazer algo parecido com isto:

public static string QueryStringAsHidden(this HtmlHelper helper)
{
    var sb = new StringBuilder();
    foreach (var key in HttpContext.Current.Request.QueryString.AllKeys)
    {
        if (! key.StartsWith("ProductSearch"))
            sb.Append(helper.Hidden(key, HttpContext.Current.Request.QueryString[key]));
    }
        return sb.ToString();
    }

Eu coloquei o .StartsWith () lá dentro, porque você não quer estar em uma página de pesquisa e submeter o texto a procurar duas vezes (e agora você pode preceder variáveis ??de paginação e específicas de pesquisa de outro com ProductSearch.

Edit: PS:. Para obter o formulário para enviar para a página atual, você não tem que fornecer explicitamente ação e controlador - você também pode enviar nulos

Edit2: Por que sequer se preocupar com um método auxiliar? :)

<% HttpContext.Current.Request.QueryString.AllKeys.Where(k => !k.StartsWith("ProductSearch")).ToList().ForEach(k => Response.Write(Html.Hidden(k, HttpContext.Current.Request.QueryString[k]))); %>

James

Outras dicas

Um direta para chamar BeginForm () não manter seus valores de string de consulta. Qualquer outra sobrecarga tende a falhar. Eu amo a facilidade de usar BeginForm () a partir de minhas formas, mas precisava de um caminho para a aula todos os meus formulários de estilo de uma certa maneira um não perder os valores de string de consulta na ação.

Aqui está o que eu vim com:

public static MvcForm BeginNormalForm<T>(this HtmlHelper<T> htmlHelper)
{
    var dictionary = new Dictionary<string, object> {{"class", "normal"}};
    var rvd = new RouteValueDictionary();
    if (htmlHelper.ViewContext.HttpContext != null && htmlHelper.ViewContext.HttpContext.Request != null)
    {
        foreach (var key in htmlHelper.ViewContext.HttpContext.Request.QueryString.AllKeys)
        {
            rvd[key] = htmlHelper.ViewContext.HttpContext.Request.QueryString[key];
        }
    }
    var form = htmlHelper.BeginForm(null, null, rvd, FormMethod.Post, dictionary);
    return form;
}

parece funcionar bem e mantém o meu atributo de classe.

Use uma das sobrecargas de BeginForm que leva routeValues ??objeto ou dicionário.

Propriedades adicionais que não estão na rota será adicionado como parâmetros de consulta.

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