这是 ASP.NET 模型绑定中的错误吗?
我在 ASP.NET MVC 中有一个简单的表单。我试图将这些结果发布到控制器操作中,但出现了奇怪的行为。
view
是一个简单的 HTML 表格:
以下是 HTML 表单视图的一部分:
<form action="/Applications/UpdateSurvey" method="post"><table id=questionsTable class=questionsTable border=1>
<thead><tr><td>Name</td><td>Answer</td><td>Name Attribute(for debugging)</td></tr> </thead><tbody>
<tr>
<td>Question 0:</td>
<td><input type='checkbox' class='checkboxes' name='updater.questions[0].responseIds' value=1 >1 <input type='checkbox' class='checkboxes' name='updater.questions[0].responseIds' value=2 >2 <input type='checkbox' class='checkboxes' name='updater.questions[0].responseIds' value=3 >3 <input type='checkbox' class='checkboxes' name='updater.questions[0].responseIds' value=4 >4 <input type='checkbox' class='checkboxes' name='updater.questions[0].responseIds' value=5 >5 </td>
<td>updater.questions[0].responseIds</td>
</tr>
<tr>
<td>Question 1:</td>
<td><input type='checkbox' class='checkboxes' name='updater.questions[1].responseIds' value=1 >1 <input type='checkbox' class='checkboxes' name='updater.questions[1].responseIds' value=2 >2 <input type='checkbox' class='checkboxes' name='updater.questions[1].responseIds' value=3 >3 <input type='checkbox' class='checkboxes' name='updater.questions[1].responseIds' value=4 >4 <input type='checkbox' class='checkboxes' name='updater.questions[1].responseIds' value=5 >5 </td>
<td>updater.questions[1].responseIds</td>
</tr>
</tbody></table>
<input type="submit" value="Save" />
</form>
绑定对象:
public class SurveyUpdater
{
public Question[] questions { get; set; }
}
public class Question
{
public int[] responseIds { get; set; }
}
控制器操作代码:
public ActionResult UpdateSurvey(SurveyUpdater updater)
{
if (updater.questions == null)
{
//I dont understand why this is getting hit
}
if (updater.questions.Length != 5)
{
//I dont understand why this is getting hit
}
return View("TestSurvey");
}
经过测试,以下是我的观察结果:
如果我至少有一个
在每个问题上选择复选框
,这工作正常,并且在我的控制器updater.questions.Length == 5
中并且数据完美绑定。如果我根本不回答其中一个问题,我只会得到一个与我跳过的数字一样大的数组:
-1
。因此,如果我没有回答问题#3,我会在控制器操作 2 中得到一个数组。通过使用 #2 的逻辑,如果我没有回答第一个问题,我只会得到
null
forupdater.questions
我想要得到的(也是我所期望的)是:
我总是会得到长度为 5
的 questions
,并且在如果我没有回答其中一个问题,我只需为该索引 responseIds
获取一个 0
大小的数组。
这是 ASP.NET MVC 模型绑定中的错误吗?如果没有,我是否缺少任何东西或有什么方法可以获得我正在寻找的所需行为?
I have a simple form in ASP.NET MVC. I am trying to post these results to a controller action and I am getting strange behavior.
The view
is a simple HTML table:
Here is part of the HTML form View:
<form action="/Applications/UpdateSurvey" method="post"><table id=questionsTable class=questionsTable border=1>
<thead><tr><td>Name</td><td>Answer</td><td>Name Attribute(for debugging)</td></tr> </thead><tbody>
<tr>
<td>Question 0:</td>
<td><input type='checkbox' class='checkboxes' name='updater.questions[0].responseIds' value=1 >1 <input type='checkbox' class='checkboxes' name='updater.questions[0].responseIds' value=2 >2 <input type='checkbox' class='checkboxes' name='updater.questions[0].responseIds' value=3 >3 <input type='checkbox' class='checkboxes' name='updater.questions[0].responseIds' value=4 >4 <input type='checkbox' class='checkboxes' name='updater.questions[0].responseIds' value=5 >5 </td>
<td>updater.questions[0].responseIds</td>
</tr>
<tr>
<td>Question 1:</td>
<td><input type='checkbox' class='checkboxes' name='updater.questions[1].responseIds' value=1 >1 <input type='checkbox' class='checkboxes' name='updater.questions[1].responseIds' value=2 >2 <input type='checkbox' class='checkboxes' name='updater.questions[1].responseIds' value=3 >3 <input type='checkbox' class='checkboxes' name='updater.questions[1].responseIds' value=4 >4 <input type='checkbox' class='checkboxes' name='updater.questions[1].responseIds' value=5 >5 </td>
<td>updater.questions[1].responseIds</td>
</tr>
</tbody></table>
<input type="submit" value="Save" />
</form>
Binding Object:
public class SurveyUpdater
{
public Question[] questions { get; set; }
}
public class Question
{
public int[] responseIds { get; set; }
}
Controller Action code:
public ActionResult UpdateSurvey(SurveyUpdater updater)
{
if (updater.questions == null)
{
//I dont understand why this is getting hit
}
if (updater.questions.Length != 5)
{
//I dont understand why this is getting hit
}
return View("TestSurvey");
}
After testing, here are my observations:
If I have at least one
CheckBox
selected on each of the questions, this works fine and in my controllerupdater.questions.Length == 5
and the data binds perfectly.If I don't answer one of the questions at all, I only get an array as big as the number I skipped:
-1
. So if I didn't answer Question #3, I get an array in my controller action of 2.By using the logic of #2, if I don't answer the first question, I simply get
null
forupdater.questions
What I want to get (and what I expected) is that:
I would always get questions
with a length of 5
and in the cases where I didn't answer one of the questions, I would simply get a 0
sized array for that index responseIds
.
Is this a bug in ASP.NET MVC model binding? If not, is there anything I am missing or any way to get the desired behavior that I am looking for?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为问题在于,当没有选择任何选项时,输入甚至不会在请求参数中传回。解决这个问题的一种方法是有一个默认的隐藏复选框,其中包含一个已知值,您可以过滤掉最初为每个问题选择的值(如果您愿意,可以选择“未回答”复选框)。这将保证您获得每个问题的选择,并且数组中的每个元素都存在一个请求参数。
从发回的内容的角度来考虑。仅发布那些具有值、名称且未禁用的元素。如果不是所有的问题都有值,那么它应该创建多少个数组项?它最多可以猜测最后选择的项目应该是数组的大小——但是对于中间的任何项目应该使用什么值?框架无法读懂您的想法,并且可以说,不应该读懂您的想法,尽管为类型提供默认值可能是合理的。 IMO,最好省略该值,从而强制开发人员在需要时提供默认值。这似乎就是正在发生的事情。
The problem, I think, is because when no selections are chosen, the inputs are not even passed back in the request parameters. One way around this would be to have a default, hidden checkbox containing a known value that you could filter out selected initially for each question (a "not answered" checkbox, if you will). That would guarantee that you get a selection for each question and that a request parameter exists for each element in the array.
Think about it from the perspective of what gets posted back. Only those elements that have values, have names, and aren't disabled get posted. If not all the questions have values, then how many array items should it create? At best it can guess that the last item selected should be the size of the array -- but what values should it use for any items in between? The framework can't read your mind and, arguably, shouldn't though providing the default value for the type might be reasonable. IMO, it would be better to just omit the value and, thus, force the developer to provide the default if desired. That seems to be what is happening.