2011-01-13 31 views
1

我發現Html.BeginForm()自動使用RawUrl(即QueryStringParamters)填充routeValueDictionary。不過,我需要,所以我需要使用override當我這樣做的查詢字符串值不被自動添加到RouteValueDictionary指定一個HtmlAttribute ...如何使用Html.BeginForm()將QueryString值轉換爲RouteValueDictionary?

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

。我怎樣才能做到這一點?

這是我最好的嘗試,但它似乎並沒有工作。

<% 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" })) 
     {%> ... 

我的控制器動作看起來像這樣...

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

但「RETURNURL」的值,它是查詢字符串的一部分,始終是NULL,除非我用的是默認的無參數Html.BeginForm()在我看來。

感謝, 賈斯汀

+0

你從來沒有在你的路線值的字典提到`returnUrl`,或你有? – xandy 2011-01-13 00:44:09

+0

routeValueDictionary變量假設用Request.QueryString中的所有鍵/值對填充。我可以通過使用新的{returnUrl = Request.QueryString [「ReturnUrl」]}來破解它,但是如果查詢字符串中存在多於ReturnUrl的內容。 – Justin 2011-01-13 01:08:12

回答

5

你可以寫一個幫手:

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

然後:

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

檢查安全Html.BeginForm()的源代碼在http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/FormExtensions.cs沒有幫助太多,但它顯示了無參數方法做你想做的原因 - 它實際上是從請求中設置formAction網址。

如果你寧願有查詢字符串繼續作爲查詢字符串,而不是可能是POST的一部分,這裏是另一種延伸:

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