我有一个观点:
@{
var i = 0;
}
@foreach (var field in Model.ConsentQuestions)
{
<div class="form-group">
<div class="control-label col-md-8">
@Html.Label(string.Format("ConsentQuestions[{0}].Key", i), field.Key)
@Html.Hidden(string.Format("ConsentQuestions[{0}].Key", i), field.Key)
</div>
<p class="col-md-2">
@Html.RadioButton(string.Format("ConsentQuestions[{0}].Value", i), true, htmlAttributes: new { id = string.Format("question{0}-true", i) })
<label for="question@(i)-true">Yes</label>
@Html.RadioButton(string.Format("ConsentQuestions[{0}].Value", i), false, htmlAttributes: new { id = string.Format("question{0}-false", i) })
<label for="question@(i)-false">No</label>
</p>
</div>
i++;
}
Model.ConsentQuestions
是IEnumerable<KeyValuePair<string, bool>>
(原因是问题是用户可定义的)。无论出于何种原因,活页夹都无法弄清楚这一点。通常这种索引对集合很好(我正在做与其他IEnumerables类似的东西,没有问题)。奇怪的是,如果我断开我的验证方法,它会看到ConsentQuestions中有正确数量的项目,除了每个KVP都是{&#34;&#34;,false}。
我想知道如何纠正问题并获取表单中的值进行绑定。
编辑:我确实有一个看似有效的解决方案,使用继承自DefaultModelBinder
的类,然后覆盖GetPropertyValue
以正确看controllerContext.HttpContext.Request.Form
..虽然这很好,但我仍然想知道为什么在这种情况下它不起作用。
答案 0 :(得分:2)
正如我的评论中提到的(除了拼写错误),你需要使用List,而不是IEnumerable(因为它不能在运行时由绑定器索引)并在索引属性上使用For
帮助器
public class TestModel
{
public List<KeyValuePair<string,bool>> ConsentQuestions { get; set; }
public TestModel()
{
var consentQuestions = new List<KeyValuePair<string,bool>>();
for (int i = 1; i <= 10; i++)
{
consentQuestions.Add(new KeyValuePair<string,bool>("Question " + i.ToString(), i % 2 == 0));
}
this.ConsentQuestions = consentQuestions;
}
}
然后我在索引元素属性上应用了...For
版本的帮助程序:
<div class="control-label col-md-8">
@Html.DisplayFor(m=>m.ConsentQuestions[i].Key)
</div>
<p class="col-md-2">
@Html.RadioButtonFor(m=>m.ConsentQuestions[i].Value, true, htmlAttributes: new { id = string.Format("question{0}-true", i) })
<label for="question@(i)-true">Yes</label>
@Html.RadioButtonFor(m => m.ConsentQuestions[i].Value, false, htmlAttributes: new { id = string.Format("question{0}-false", i) })
<label for="question@(i)-false">No</label>
</p>
注意:我将HiddenFor
更改为DisplayFor
以查看问题(随时调整)。
我一直在检查生成的输出,仅的区别在于,使用第一种绑定方式无法匹配现有值(第二种方式有效)。这适用于使用实体类或KeyValuePair(没有区别)。看起来RadioButton
绑定器已损坏,但RadionButtonFor
不是:
@Html.RadioButton("ConsentQuestions[" + i.ToString() + "].Value", true, htmlAttributes: new { id = string.Format("question{0}-true", i) })
@Html.RadioButtonFor(m => m.ConsentQuestions[i].Value, false, htmlAttributes: new { id = string.Format("question{0}-false", i) })
这显然有点奇怪,因为它应该工作相同,但解决方案仍然只是使用帮助器的For
版本。 强类型代码总是比字符串更好。
答案 1 :(得分:1)
只需更改模型即可使用Dictionary
(字面意思是KeyValuePairs
列表)。您甚至不需要更改视图。
这样的事情:
public ActionResult AnswerQuestions(IEnumerable<KeyValuePair<string, bool>> ConsentQuestions)
{
// Do stuff
}
将改为:
public ActionResult AnswerQuestions(Dictionary<string, bool> ConsentQuestions)
{
// Do stuff
}
主要区别在于,除IEnumerable
所拥有的属性外,还有.Comparer
,.ContainsKey()
,.ContainsValue()
,.Count
,{{ 1}},.Keys
和.TryGetValue()
。