2012-01-27 46 views
7

我有一个多步骤的设置过程,我想只在URL相关的时候将查询字符串参数传递给URL。MVC3 Html.BeginForm - 传递参数作为RouteValueDictionary失败

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

@using(Html.BeginForm())

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

但是,我需要为我的表单分配一个类用于样式目的。

我尝试:

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

其产生:

<form action="/Account/Profile?Count=1&amp;Keys=System.Collections.Generic.Dictionary%602%2BKeyCollection%5BSystem.String%2CSystem.Object%5D&amp;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&amp;cats=dogs" class="mainForm" method="post">

我要提到我宁愿不要做类似传入new {key = value}代替,因为有相当多的逻辑来决定什么,我会沿着下一步路过。

关于在这里做什么的任何建议?

我受到这个看似简单的任务的阻碍,我肯定错过了一些非常明显的东西。

+0

也许在这个其他职位的答案可能有点帮助? http://stackoverflow.com/questions/1219223/asp-net-mvc-getting-html-beginform-to-remember-querystring-params-when-submi – summea 2012-01-27 03:46:49

回答

10

指定参数时,并且是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作为字典或两者都作为匿名对象。

+0

@Darin季米特洛夫你可以检查我的问题,有一些相似之处:http://stackoverflow.com/questions/12142356/send-an-object-as-a-parameter-to-post-action-in-asp-net -mvc3 – Saeid 2012-08-27 14:00:59

+0

你的解决方案适用于我的情况,但我不明白为什么在类变量之前使用@符号。任何人都可以解释这里发生了什么?谢谢。 – northben 2013-01-27 22:09:55

+0

@northben,它的使用是因为'class'是C#中的一个保留关键字。您可以在C#规范中阅​​读更多关于它的信息:http://msdn.microsoft.com/en-us/library/aa664670.aspx – 2013-01-28 06:38:08

0

只是一个想法,但即使是多步骤的形式,你是不是想要选择全部GET或POST?在上面的例子中,它看起来像使用POST与表单...但仍然尝试使用GET。

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

否则,用户可以更容易地更改值,对吧? (虽然,可能无法在该申请事项而这大多只是回味无穷。)

0

让你在使用此重载:

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

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

根据文档:

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

另一种选择是不使用HTML帮助程序并手动创建表单标签 - 虽然这样做会挫败具有HTML帮助程序的目的。

+0

我应该早在我的帖子中提到的 - 它需要一点确定我想要保留/清理/添加参数的逻辑。也许我应该追求一个自定义的HtmlHelper? – Erica 2012-01-27 02:53:51

+0

我不确定自定义的HtmlHelper在这里购买了什么 - 逻辑必须去某个地方。 – 2012-01-27 10:45:17

4

下面的工作。

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

的路由值由对象创建初始化语法即新的{键=值}是由滤波器产生

+0

我应该提到我不希望直接使用对象初始化语法,即新{key = value},因为它需要我的代码中的一些逻辑来确定我想传递的内容。 – Erica 2012-01-27 02:48:21