2011-01-13 8 views
1

Ich habe festgestellt, dass Html.BeginForm() automatisch das routeValueDictionary mit dem RawUrl auffüllt (dh. QueryStringParamters). Allerdings brauche ich eine HtmlAttribute angeben, damit ich die Überschreibung verwenden müssen ...Wie bekomme ich die QueryString-Werte in ein RouteValueDictionary mit Html.BeginForm()?

public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, FormMethod method, object htmlAttributes) 

Wenn ich die Abfrage-Zeichenfolge-Werte tun, werden nicht automatisch in die Routevaluedictionary hinzugefügt. Wie kann ich das erreichen?

Hier ist mein bester Versuch, aber es scheint nicht zu funktionieren.

<% RouteValueDictionary routeValueDictionary = new RouteValueDictionary(ViewContext.RouteData.Values); 
     foreach (string key in Request.QueryString.Keys) 
     { 
      routeValueDictionary[key] = Request.QueryString[key].ToString(); 
     } 

     using (Html.BeginForm("Login", "Membership", routeValueDictionary, FormMethod.Post, new { @class = "signin-form" })) 
     {%> ... 

Meine Controller Aktion sieht wie folgt aus ...

[HttpPost] 
    public ActionResult Login(Login member, string returnUrl) 
    { ... 

Aber der Wert von „returnUrl“, der Teil der Abfrage-Zeichenfolge ist immer NULL, wenn ich den Standard parameterlos Html.BeginForm() verwenden, Meiner Ansicht nach.

Danke, Justin

+0

Sie nie erwähnt 'returnUrl' in Ihrer Route Wert Wörterbuch oder du hast? – xandy

+0

Die Variable routeValueDictionary soll mit allen Schlüssel/Wert-Paaren im Request.QueryString gefüllt werden. Ich kann es hacken, indem ich einfach new {returnUrl = Request.QueryString ["ReturnUrl"]} verwende, aber was ist, wenn mehr als ReturnUrl in der Querystring ist. – Justin

+0

Wie sieht das von Ihrem Code generierte "

" -Tag aus? Der Grund, warum ich frage ist, weil in dem Fall, dass funktioniert, Sie eine URL wie "mysite.com?returnUrl=foobar" POSTing – marcind

Antwort

5

Sie einen Helfer schreiben konnte:

public static MvcHtmlString QueryAsHiddenFields(this HtmlHelper htmlHelper) 
{ 
    var result = new StringBuilder(); 
    var query = htmlHelper.ViewContext.HttpContext.Request.QueryString; 
    foreach (string key in query.Keys) 
    { 
     result.Append(htmlHelper.Hidden(key, query[key]).ToHtmlString()); 
    } 
    return MvcHtmlString.Create(result.ToString()); 
} 

und dann:

<% using (Html.BeginForm("Login", "Membership", null, FormMethod.Post, new { @class = "signin-form" })) { %> 
    <%= Html.QueryAsHiddenFields() %> 
<% } %> 
3

Inspizieren den Quellcode für Html.BeginForm() bei http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/FormExtensions.cs nicht hilft viel, aber es zeigt den Grund, warum die parameterlose Methode das tut, was Sie wollen - es setzt buchstäblich die formAction aus der Anfrage url.

Wenn Sie lieber die Abfragezeichenfolgeflag bleiben als Abfragezeichenfolgeflag haben würden, anstatt möglicherweise Teil eines POST sein, hier ist eine Alternative Erweiterung:

/// <summary> 
/// Turn the current request's querystring into the appropriate param for <code>Html.BeginForm</code> or <code>Html.ActionLink</code> 
/// </summary> 
/// <param name="html"></param> 
/// <returns></returns> 
/// <remarks> 
/// See discussions: 
/// * http://stackoverflow.com/questions/4675616/how-do-i-get-the-querystring-values-into-a-the-routevaluedictionary-using-html-b 
/// * http://stackoverflow.com/questions/6165700/add-query-string-as-route-value-dictionary-to-actionlink 
/// </remarks> 
public static RouteValueDictionary QueryStringAsRouteValueDictionary(this HtmlHelper html) 
{ 
    // shorthand 
    var qs = html.ViewContext.RequestContext.HttpContext.Request.QueryString; 

    // because LINQ is the (old) new black 
    return qs.AllKeys.Aggregate(new RouteValueDictionary(html.ViewContext.RouteData.Values), 
     (rvd, k) => { 
      // can't separately add multiple values `?foo=1&foo=2` to dictionary, they'll be combined as `foo=1,2` 
      //qs.GetValues(k).ForEach(v => rvd.Add(k, v)); 
      rvd.Add(k, qs[k]); 
      return rvd; 
     }); 
} 
+0

Ihr Code immer noch doppelte Schlüssel in kommagetrennte Listen verwandelt - wollten Sie das verhindern? Es ist nicht 100% klar von Ihrem Kommentar. – dtanders

+0

@dtanders mein Kommentar bedeutete, dass ich nicht herausfinden konnte, wie man sie als durch Komma getrennte Werte hinzufügen kann, weil das 'RouteValueDictionary' ein Wörterbuch ist und daher keine doppelten Schlüssel haben kann – drzaus