ASP.NET MVC中将<string,string>字典绑定到复选框并返回字符串值
问题根源
Html.CheckBox是ASP.NET MVC专门为布尔值属性绑定设计的辅助方法,天生不适合多选传选项值的场景:
- 它渲染的复选框固定提交
true/false值,不会使用传入的选项文本作为提交值 - 它会自动生成一个同name的隐藏域存
false值,用来保证未选中状态下也能提交值 - 绑定到字典里
string类型的Value时,自然只能拿到布尔转换的"true"/"false",无法获取实际选中的选项内容。
另外现有写法把题目的公共隐藏域放在选项循环内,一道题有几个选项就输出几个同名hidden,虽然不影响绑定,但属于冗余代码,提交时会传输很多重复数据。
修复方法
多选题部分不要用Html.CheckBox辅助方法,直接手写原生input复选框,同时把公共隐藏域挪到选项循环外面,一道题只渲染一次:
- 同一道题的所有复选框,
name属性统一指向字典对应Value的绑定路径 - 每个复选框的
value属性直接赋值对应的选项字符串 - ASP.NET MVC默认模型绑定器会自动把同name的多个选中值拼接为逗号分隔的字符串,刚好匹配
Dictionary<string,string>的Value类型,不需要额外编写自定义绑定逻辑。
修正后的多选题渲染代码如下:
@if (question.Key.TypeId == 2) /*multiple, checkboxes*/ { // 单题仅渲染一次公共参数,避免重复提交 <input type="hidden" name="testVM.Answers[@question.Key.Id].Key" value="@question.Key.Id" /> <input type="hidden" name="testVM.Answers.Index" value="@question.Key.Id" /> <input type="hidden" name="testId" value="@Model.Test.Id" /> foreach (var option in question.Value) { <label style="display: block; margin: 4px 0;"> <input type="checkbox" name="testVM.Answers[@question.Key.Id].Value" value="@option" /> @option </label> } }
绑定效果
提交后,多选题对应字典项的Value就是逗号拼接的选中值,比如某题选中"选项B"、"选项D",绑定拿到的值就是"选项B,选项D",后续业务处理时直接调用String.Split(',')就能拆分出所有选中的选项值。
单选、文本题部分也可以顺手把公共隐藏域移到选项循环外,减少无意义的提交数据。
内容的提问来源于stack exchange,提问作者pyrokinesis
相关产品推荐
相关产品推荐

