ASP.NET MVC – Html.BeginForm() dazu bringen, sich beim Senden über GET Querystring-Parameter zu merken

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

  •  10-07-2019
  •  | 
  •  

Frage

Ich habe ein über Html.BeginForm() gerendertes Formular, das als Komponente in der Masterseite vorhanden ist, sodass es auf jeder Seite in der Anwendung angezeigt wird.Ich habe dies mit Html.RenderAction() aus der Mvc Futures-Assembly gemacht.Es handelt sich um ein einfaches Suchformular, das einige Elemente in derselben Komponente unterhalb des Suchformulars selbst aktualisiert und ein GET ausführt, sodass der Suchbegriff in der Abfragezeichenfolge erscheint.

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

Ich benötige dieses Formular, um Folgendes zu tun:

1) Beim Anhängen von „ProductsSearch“ als Abfragezeichenfolgenparameter (z. B.) sollte ein GET zu der aktuellen Seite ausgeführt werden. example.com/?ProductsSearch=test oder example.com/books/fiction?ProductsSearch=test)

2) Es sollte sich alle vorhandenen Abfragezeichenfolge-Parameter merken, die bereits in der Abfragezeichenfolge enthalten sind, und sie beibehalten, nachdem Sie z. B. auf die Schaltfläche „Suchen“ geklickt haben. example.com/myOrders?page=2 Nachdem Sie auf „Suchen“ geklickt haben, sollte es zu gehen example.com/myOrders?page=2&ProductsSearch=test)

Ich kann 1) damit hinbekommen, aber 2) klappt nicht.

Ich bin mir sicher, dass normalerweise für einen From-to-GET-Vorgang und das Anhängen von Querystring-Parametern versteckte Formularfelder erforderlich sind, sodass ich eine Hilfsfunktion schreiben könnte, die automatisch eine Reihe versteckter Formularfelder für alle Querystring-Werte hinzufügt, aber ich wollte überprüfen, ob das so ist Das ist kein einfacherer Ansatz, oder vielleicht mache ich es falsch.

Prost!

War es hilfreich?

Lösung

Sie müssen die versteckte Formularfeldmethode tun.

Auch wenn Sie die gesamte Abfragezeichenfolgeflag bis zum Ende der URL im action-Attribut des

Tag anhängen könnte, Browser nicht zahlen Aufmerksamkeit auf diese, wenn GET Formularen zu tun.

Ihre Methode ist nicht allzu schwierig; Sie würden wollen, so etwas tun:

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

ich die .StartsWith put () dort, weil Sie den Suchbegriff zweimal nicht auf einer Suchseite sein wollen und einreichen (und jetzt können Sie Paging und andere Suchspezifische Variablen mit ProduktSuche voranstellen.

Edit: PS:. Das Formular Um auf die aktuelle Seite zu schreiben, müssen Sie nicht explizit Aktion und Steuerung zur Verfügung zu stellen - auch nulls senden

Edit2: Warum auch mit einer Helfer-Methode der Mühe machen? :)

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

James

Andere Tipps

Eine direkte Begin () aufrufen, wird Ihre Abfrage-String-Werte halten. Jede andere Überlastung neigt zum Scheitern verurteilt. Ich liebe die Einfachheit der Verwendung von Begin () von meinem Formen, sondern musste einen Weg Klasse all meinen gestylten Formen eine gewisse Art und Weise eine nicht die Query-String-Werte in der Aktion verlieren.

Hier ist, was ich kam mit:

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

Es scheint gut zu funktionieren und hält mein Klassenattribut.

Verwenden Sie eine der Überladungen von BeginForm, die ein routeValues-Objekt oder -Wörterbuch akzeptiert.

Zusätzliche Eigenschaften, die nicht in der Route enthalten sind, werden als Abfrageparameter hinzugefügt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top