2011-01-13 35 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; 
     }); 
}