ASP.NET MVC - Получение Html.BeginForm () для запоминания параметров строки запроса при отправке через GET - PullRequest
4 голосов
/ 02 августа 2009

У меня есть форма, отображаемая с помощью Html.BeginForm (), она существует как компонент на главной странице, поэтому она появляется на каждой странице приложения. Я сделал это с помощью Html.RenderAction () из сборки Mvc Futures. Это простая форма поиска, которая обновляет некоторые элементы в одном и том же компоненте под самой формой поиска и выполняет GET, чтобы поисковый термин появлялся в строке запроса.

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

Мне нужна эта форма, чтобы сделать следующее:

1) Он должен выполнить GET для любой текущей страницы при добавлении «ProductsSearch» в качестве параметра строки запроса (например, example.com /? ProductsSearch = test или example.com / книги / фантастика? ProductsSearch = тест )

2) Следует помнить о любых существующих параметрах строки запроса, которые уже находятся в строке запроса, и сохранять их после нажатия кнопки «Поиск», например. example.com / myOrders? Page = 2 после того, как поиск нажмет, он должен перейти на example.com / myOrders? Page = 2 & ProductsSearch = test )

Я могу заставить это сделать 1), но не могу 2).

Я полагаю, что обычно для операций from и GET и добавления параметров строки запроса необходимо иметь скрытые поля формы, чтобы я мог написать служебную функцию, которая автоматически добавляет набор скрытых полей формы для любых значений строки запроса, но я хотел проверить что не было более легкого подхода, или, может быть, я ошибаюсь.

Ура!

Ответы [ 3 ]

9 голосов
/ 02 августа 2009

Вам нужно будет сделать метод скрытого поля формы.

Даже если вы можете присоединить всю строку запроса к концу URL-адреса в атрибуте действия тега , браузеры не обращают на это внимания при отправке формы GET.

Ваш метод не слишком сложен; Вы хотели бы сделать что-то вроде этого:

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();
    }

Я добавил туда .StartsWith (), потому что вы не хотите находиться на странице поиска и дважды отправлять строку поиска (и теперь вы можете добавить в заголовок подкачки и другие переменные, специфичные для поиска, с помощью ProductSearch.

Редактировать: PS: Чтобы получить форму для публикации на текущей странице, вам не нужно явно указывать действие и контроллер - вы также можете отправлять нули.

Edit2: Зачем вообще использовать вспомогательный метод? :)

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

Джеймс

1 голос
/ 13 мая 2011

Прямой вызов BeginForm () сохраняет значения строки запроса. Любая другая перегрузка имеет тенденцию терпеть неудачу. Мне нравится простота использования BeginForm () из моих форм, но мне нужен был способ классифицировать все мои стилизованные формы определенным образом, чтобы не потерять значения строки запроса в действии.

Вот что я придумал:

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;
}

Кажется, работает хорошо и сохраняет мой атрибут класса.

0 голосов
/ 02 августа 2009

Используйте одну из перегрузок BeginForm, которая принимает объект routeValues ​​или словарь.

Дополнительные свойства, отсутствующие в маршруте, будут добавлены в качестве параметров запроса.

...