【问题标题】:How do I get the QueryString values into a the RouteValueDictionary using Html.BeginForm()?如何使用 Html.BeginForm() 将 QueryString 值放入 RouteValueDictionary?
【发布时间】:2011-01-13 00:35:10
【问题描述】:

我发现Html.BeginForm() 自动使用 RawUrl(即 QueryStringParamters)填充 routeValueDictionary。但是我需要指定一个 HtmlAttribute 所以我需要使用覆盖...

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

当我这样做时,QueryString 值不会自动添加到 RouteValueDictionary。我怎样才能做到这一点?

这是我最好的尝试,但它似乎不起作用。

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

但作为 QueryString 一部分的“returnUrl”的值始终为 NULL,除非我在视图中使用默认的无参数 Html.BeginForm()。

谢谢, 贾斯汀

【问题讨论】:

  • 你从未在你的路由值字典中提到returnUrl,或者你有?
  • RouteValueDictionary 变量假定填充了 Request.QueryString 中的所有键/值对。我可以通过使用 new { returnUrl = Request.QueryString["ReturnUrl"] } 来破解它,但是如果查询字符串中的 ReturnUrl 不止一个怎么办。
  • 你的代码生成的&lt;form&gt;标签是什么样子的?我问的原因是因为在可行的情况下,您可能会发布到像“mysite.com?returnUrl=foobar”这样的网址

标签: asp.net-mvc html.beginform querystringparameter


【解决方案1】:

你可以写一个助手:

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

【讨论】:

    【解决方案2】:

    http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/FormExtensions.cs 检查Html.BeginForm() 的源代码并没有太大帮助,但它显示了无参数方法执行您想要的操作的原因——它实际上是从请求url 设置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;
            });
    }
    

    【讨论】:

    • 您的代码仍然会将重复的键转换为逗号分隔的列表 - 您的意思是要防止这种情况发生吗?您的评论不是 100% 清楚的。
    • @dtanders 我的评论意味着我无法弄清楚如何防止将它们添加为逗号分隔值,因为 RouteValueDictionary 是字典,因此不能有重复的键
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多