在 MVC5 中绑定复杂类型
Binding Complex Types in MVC5
我是一名新手开发人员,正在尝试使用 asp .net mvc 5 开发 Web 应用程序供个人使用。该网站是一种测验工具,我可以插入具有含义的俄语单词并使用这些单词准备测验。
当我尝试编写测验页面和 post 操作方法的数据时,我遇到了一些我无法解决的问题。我遍历模型,读取数据并将它们写入页面。现在,我想做的是,当我 post 表单时,我想获取每个问题字符串和选定的答案(可能采用这种格式:imgur.com/QETnafx)。因此,我可以轻松地检查答案字符串是否正确。
我查看了以下教程:
Phil Haack 的模型绑定到列表和 ASP.NET 模型绑定到数组、列表、集合、字典的连线格式 Scott Hanselman
希望我把情况说清楚了。如果您需要更多信息,我很乐意提供。
ViewModel
public class QuizInitializationModel
{
public List<Question> Questions { get; set; }
}
public class QuestionString
{
public int Id { get; set; }
public string WordString { get; set; }
}
public class Question
{
public QuestionString QuestionString { get; set; }
public List<AnswerItem> Answers { get; set; }
}
public class AnswerItem
{
public int Id { get; set; }
public string WordString { get; set; }
}
VIEW
@using (Html.BeginForm("Begin", "Quiz", FormMethod.Post))
{
<table class="table table-striped table-condensed table-bordered">
@for (int i = 0; i < Model.Questions.Count; i++)
{
<tr>
<td>
@Html.Label(Model.Questions[i].QuestionString.WordString)
</td>
<td>
@for (int item = 0; item < Model.Questions[0].Answers.Count; item++)
{
@Html.Label(Model.Questions[i].Answers[item].WordString)@:
@Html.RadioButton("array" + "[" + @i + "]" + "." + Model.Questions[i].QuestionString.WordString, Model.Questions[i].Answers[item].Id)<br />
}
</td>
</tr>
}
</table>
<input type="submit" value="Send" class="btn btn-primary" />
}
输出
<form action="/Admin/Quiz/Begin" method="post">
<table class="table table-striped table-condensed table-bordered">
<tr>
<td>
<label for="">вулкан</label>
</td>
<td>
<label for="trade">trade</label>
<input id="array_0________" name="array[0].вулкан" type="radio" value="18" /><br />
<label for="volcano">volcano</label>
<input id="array_0________" name="array[0].вулкан" type="radio" value="24" /><br />
<label for="talk__conversation">talk, conversation</label>
<input id="array_0________" name="array[0].вулкан" type="radio" value="15" /><br />
<label for="time">time</label>
<input id="array_0________" name="array[0].вулкан" type="radio" value="13" /><br />
<label for="income">income</label>
<input id="array_0________" name="array[0].вулкан" type="radio" value="21" /><br />
</td>
</tr>
<tr>
<td>
<label for="">мама</label>
</td>
<td>
<label for="universe">universe</label>
<input id="array_1______" name="array[1].мама" type="radio" value="25" /><br />
<label for="peace">peace</label>
<input id="array_1______" name="array[1].мама" type="radio" value="2" /><br />
<label for="value">value</label>
<input id="array_1______" name="array[1].мама" type="radio" value="20" /><br />
<label for="mom__mama">mom, mama</label>
<input id="array_1______" name="array[1].мама" type="radio" value="17" /><br />
<label for="industry">industry</label>
<input id="array_1______" name="array[1].мама" type="radio" value="19" /><br />
</td>
</tr>
</table>
我该如何修复像 "array_1______" 这样的标签的 ID?
当我将此代码 "array" + "[" + @i + "]" + "." 添加到 RadioButton 控件时,它们出现了,目的是为每个控件分配一个索引回答。
Html 助手用下划线替换无效字符(句点实际上不是无效的,但会导致 jquery 出现问题,因此它也替换了下划线)。但是 id
属性不是问题,尽管您正在生成无效的重复项 html.
您为单选按钮手动生成的 name
属性与模型中的任何 属性 都没有关系,因此当您 post 返回时不会被绑定。您的模型需要包含一个 属性,您可以将所选答案绑定到。修改Question
模型为
public class Question
{
public QuestionString QuestionString { get; set; }
public List<AnswerItem> Answers { get; set; }
public int SelectedAnswer { get; set; } // add this
}
并将视图修改为
@using (Html.BeginForm()) // note parameter not necessary if your posting to the same controller/action
{
@for (int i = 0; i < Model.Questions.Count; i++)
{
...
@Html.HiddenFor(m => m.Questions[i].QuestionString.Id)
<h2>@Model.Questions[i].QuestionString.WordString)</h2>
...
@foreach(var answer in Model.Questions[i].Answers)
{
var id = string.Format("{0}-{1}", @i, answer.Id);
@Html.Label(id, answer.WordString)
@Html.RadioButtonFor(m => m.Questions[i].SelectedAnswer, answer.ID, new { id = id })
}
....
}
<input type="submit" value="Send" class="btn btn-primary" />
}
单选按钮现在绑定到 SelectedAnswer
属性,当您 post 返回时,该值将是所选 AnswerItem
另请注意:
- 已为问题 ID 添加隐藏输入,因此
问题可以在 post back
上找到
- 问题文本在标题标签中(可以是另一个标签),但是
label 不合适 - label 是与 a 关联的元素
控件(用于将焦点设置到控件),但您没有
关联控件
- 在
foreach
循环中创建了一个唯一的 ID,因此您可以给每个
单选按钮一个唯一的 id(所以 html 是有效的)并关联
带有按钮的标签(答案文本)
我是一名新手开发人员,正在尝试使用 asp .net mvc 5 开发 Web 应用程序供个人使用。该网站是一种测验工具,我可以插入具有含义的俄语单词并使用这些单词准备测验。
当我尝试编写测验页面和 post 操作方法的数据时,我遇到了一些我无法解决的问题。我遍历模型,读取数据并将它们写入页面。现在,我想做的是,当我 post 表单时,我想获取每个问题字符串和选定的答案(可能采用这种格式:imgur.com/QETnafx)。因此,我可以轻松地检查答案字符串是否正确。
我查看了以下教程: Phil Haack 的模型绑定到列表和 ASP.NET 模型绑定到数组、列表、集合、字典的连线格式 Scott Hanselman
希望我把情况说清楚了。如果您需要更多信息,我很乐意提供。
ViewModel
public class QuizInitializationModel
{
public List<Question> Questions { get; set; }
}
public class QuestionString
{
public int Id { get; set; }
public string WordString { get; set; }
}
public class Question
{
public QuestionString QuestionString { get; set; }
public List<AnswerItem> Answers { get; set; }
}
public class AnswerItem
{
public int Id { get; set; }
public string WordString { get; set; }
}
VIEW
@using (Html.BeginForm("Begin", "Quiz", FormMethod.Post))
{
<table class="table table-striped table-condensed table-bordered">
@for (int i = 0; i < Model.Questions.Count; i++)
{
<tr>
<td>
@Html.Label(Model.Questions[i].QuestionString.WordString)
</td>
<td>
@for (int item = 0; item < Model.Questions[0].Answers.Count; item++)
{
@Html.Label(Model.Questions[i].Answers[item].WordString)@:
@Html.RadioButton("array" + "[" + @i + "]" + "." + Model.Questions[i].QuestionString.WordString, Model.Questions[i].Answers[item].Id)<br />
}
</td>
</tr>
}
</table>
<input type="submit" value="Send" class="btn btn-primary" />
}
输出
<form action="/Admin/Quiz/Begin" method="post">
<table class="table table-striped table-condensed table-bordered">
<tr>
<td>
<label for="">вулкан</label>
</td>
<td>
<label for="trade">trade</label>
<input id="array_0________" name="array[0].вулкан" type="radio" value="18" /><br />
<label for="volcano">volcano</label>
<input id="array_0________" name="array[0].вулкан" type="radio" value="24" /><br />
<label for="talk__conversation">talk, conversation</label>
<input id="array_0________" name="array[0].вулкан" type="radio" value="15" /><br />
<label for="time">time</label>
<input id="array_0________" name="array[0].вулкан" type="radio" value="13" /><br />
<label for="income">income</label>
<input id="array_0________" name="array[0].вулкан" type="radio" value="21" /><br />
</td>
</tr>
<tr>
<td>
<label for="">мама</label>
</td>
<td>
<label for="universe">universe</label>
<input id="array_1______" name="array[1].мама" type="radio" value="25" /><br />
<label for="peace">peace</label>
<input id="array_1______" name="array[1].мама" type="radio" value="2" /><br />
<label for="value">value</label>
<input id="array_1______" name="array[1].мама" type="radio" value="20" /><br />
<label for="mom__mama">mom, mama</label>
<input id="array_1______" name="array[1].мама" type="radio" value="17" /><br />
<label for="industry">industry</label>
<input id="array_1______" name="array[1].мама" type="radio" value="19" /><br />
</td>
</tr>
</table>
我该如何修复像 "array_1______" 这样的标签的 ID? 当我将此代码 "array" + "[" + @i + "]" + "." 添加到 RadioButton 控件时,它们出现了,目的是为每个控件分配一个索引回答。
Html 助手用下划线替换无效字符(句点实际上不是无效的,但会导致 jquery 出现问题,因此它也替换了下划线)。但是 id
属性不是问题,尽管您正在生成无效的重复项 html.
您为单选按钮手动生成的 name
属性与模型中的任何 属性 都没有关系,因此当您 post 返回时不会被绑定。您的模型需要包含一个 属性,您可以将所选答案绑定到。修改Question
模型为
public class Question
{
public QuestionString QuestionString { get; set; }
public List<AnswerItem> Answers { get; set; }
public int SelectedAnswer { get; set; } // add this
}
并将视图修改为
@using (Html.BeginForm()) // note parameter not necessary if your posting to the same controller/action
{
@for (int i = 0; i < Model.Questions.Count; i++)
{
...
@Html.HiddenFor(m => m.Questions[i].QuestionString.Id)
<h2>@Model.Questions[i].QuestionString.WordString)</h2>
...
@foreach(var answer in Model.Questions[i].Answers)
{
var id = string.Format("{0}-{1}", @i, answer.Id);
@Html.Label(id, answer.WordString)
@Html.RadioButtonFor(m => m.Questions[i].SelectedAnswer, answer.ID, new { id = id })
}
....
}
<input type="submit" value="Send" class="btn btn-primary" />
}
单选按钮现在绑定到 SelectedAnswer
属性,当您 post 返回时,该值将是所选 AnswerItem
另请注意:
- 已为问题 ID 添加隐藏输入,因此 问题可以在 post back 上找到
- 问题文本在标题标签中(可以是另一个标签),但是 label 不合适 - label 是与 a 关联的元素 控件(用于将焦点设置到控件),但您没有 关联控件
- 在
foreach
循环中创建了一个唯一的 ID,因此您可以给每个 单选按钮一个唯一的 id(所以 html 是有效的)并关联 带有按钮的标签(答案文本)