【问题标题】:MVC3 Html.BeginForm - passing arguments as RouteValueDictionary failsMVC3 Html.BeginForm - 作为 RouteValueDictionary 传递参数失败
【发布时间】:2012-01-27 02:28:43
【问题描述】:

我有一个多步骤设置过程,我希望仅在相关的情况下传递附加到 URL 的查询字符串参数。

http://localhost:6618/Account/Profile?wizard=true&cats=dogs

@using( Html.BeginForm() )

效果很好。它产生了:<form action="/Account/Profile?setup=true&cats=dogs" method="post"> 即它传递到 POST 操作中的任何原始查询字符串参数,然后在该控制器操作中,我可以选择哪些与传递到下一步相关,或者需要添加,通过添加到RouteValues 和 RedirectToResult。

但是,我需要为我的表单分配一个类以进行样式设置。

我试过了:

@using( Html.BeginForm( "Profile", "Account", args, FormMethod.Post, new { @class = "mainForm" } ) )

产生:

<form action="/Account/Profile?Count=1&Keys=System.Collections.Generic.Dictionary%602%2BKeyCollection%5BSystem.String%2CSystem.Object%5D&Values=System.Collections.Generic.Dictionary%602%2BValueCollection%5BSystem.String%2CSystem.Object%5D" class="mainForm" method="post">

args 由过滤器生成,是一个 RouteValueDictionary)。规范 http://msdn.microsoft.com/en-us/library/dd505151.aspx 表明您可以使用 System.Web.Routing.RouteValueDictionary 传递参数。

我想要的是<form action="/Account/Profile?setup=true&cats=dogs" class="mainForm" method="post">

我应该提一下,我不想做类似传递 new {key = value} 之类的事情,因为有相当多的逻辑可以确定我将传递到下一步的内容。

有什么建议可以在这里做什么吗?

我被这个看似简单的任务所困扰,并且肯定错过了一些非常明显的东西。

【问题讨论】:

标签: asp.net-mvc-3 html-helper


【解决方案1】:

args 由过滤器生成,是一个 RouteValueDictionary

这是这里的关键点。在这种情况下,请确保您使用的是 BeginForm 方法的 correct overload

@using(Html.BeginForm(
    "Profile", 
    "Account",   
    args, 
    FormMethod.Post, 
    new RouteValueDictionary(new { @class = "mainForm" })
))
{
    ...
}

注意到最后一个参数了吗?它必须是 IDictionary<string, object> 才能正常工作。

在您的示例中,被选中的是this overload。但是由于您为 routeValues 参数而不是匿名对象传递了 RouteValueDictionary,因此它会变得混乱。

因此,您应该将 routeValues 和 htmlAttributes 作为字典,或者将两者都作为匿名对象。

【讨论】:

  • @Darin Dimitrov 你能检查我的问题吗,有一些相似之处:stackoverflow.com/questions/12142356/…
  • 您的解决方案适用于我的情况,但我不明白为什么在类变量之前使用 @ 符号。谁能解释这里发生了什么?谢谢。
  • @northben,之所以使用它是因为class 是 C# 中的保留关键字。您可以在 C# 规范中阅读更多相关信息:msdn.microsoft.com/en-us/library/aa664670.aspx
【解决方案2】:

以下将起作用。

 @using (Html.BeginForm("Profile", "Account", new { id=122}, FormMethod.Post, new { @class = "mainForm" }))

路由值由对象初始化语法创建,即 new {key = value}

【讨论】:

  • 我应该提到我不想直接使用对象初始化语法,即 new {key = value},因为它需要我的代码中的一些逻辑来确定我想要传递的内容.
【解决方案3】:

所以你正在使用这个重载:

http://msdn.microsoft.com/en-us/library/dd460542.aspx

是否可以使 args 成为具有键和值的简单对象?我认为这可能会解决您的问题。

根据文档:

通过检查对象的属性通过反射检索参数。这个对象通常是使用对象初始化器语法创建的。 - 这似乎是正在发生的事情 - 它使用反射来获取路由字典的属性 - 属性是键(字符串集合)和值(集合对象)

另一种选择是不使用 html 帮助程序并手动创建表单标签——尽管这会破坏拥有 html 帮助程序的目的。

【讨论】:

  • 我应该在我的帖子前面提到过 - 需要一些逻辑来确定我想要保留/清理/添加到参数的确切内容。也许我应该追求一个自定义的 HtmlHelper?
  • 我不确定自定义 HtmlHelper 在这里给你买了什么——逻辑必须去某个地方。
【解决方案4】:

只是一个想法,但是,即使对于多步骤表单,您是否不想选择使其全部为 GET 或 POST?在上面的示例中...看起来您正在使用 POST 和表单...但仍在尝试使用 GET。

为什么不一直使用隐藏的 POST 值(使用 HTML INPUT)?

否则,用户可以更轻松地更改值,对吗? (不过,这在此应用程序中可能无关紧要。这主要是值得深思的。)

【讨论】:

    猜你喜欢
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 2014-11-29
    • 2014-02-05
    • 1970-01-01
    • 2012-02-27
    相关资源
    最近更新 更多