MVC 4 获取选定单选按钮的值
MVC 4 getting values of selected radio buttons
我刚刚涉足 MVC (v4) 的世界,但在获取单选按钮列表列表的实际选定值时遇到了真正的麻烦。我正在从 Umbraco 数据库中提取数据(但我想我尝试做的事情的原理是一样的),其中有问题列表,每个问题都有一个答案列表。我会 post 到目前为止我所做的一切,希望比我更聪明的人能给我指明正确的方向:
这是我的内容结构
我的模型
namespace ICASolution.Models
{
public class MultipleChoiceViewModel
{
public int iQuestionID { get; set; }
public string zQuestionTitle { get; set; }
public string zQuestionText { get; set; }
public List<Answers> lAnswers { get; set; }
}
public class Answers
{
public int iAnswerID { get; set; }
public string zAnswerText { get; set; }
public bool bCorrect { get; set; }
public string selectedAnswer { get; set; }
}
}
我的表面控制器:
namespace ICASolution.Controllers
{
public class MultipleChoiceSurfaceController : SurfaceController
{
//
// GET: /MultipleChoiceSurface/
//public ActionResult Index()
//{
// return PartialView("MultipleChoice", new MultipleChoiceViewModel());
//}
[HttpPost]
public ActionResult Grade(MultipleChoiceViewModel model)
{
return RedirectToCurrentUmbracoPage();
}
public ActionResult Index()
{
var TestPage = Umbraco.Content(CurrentPage.Id);
var questions = new List<MultipleChoiceViewModel>();
foreach (var child in TestPage.Children)
{
var questionid = child.Id;
var questiontitle = child.GetPropertyValue("questionTitle");
var questiontext = child.GetPropertyValue("questionText");
questions.Add(new MultipleChoiceViewModel { iQuestionID = questionid, zQuestionTitle = questiontitle, zQuestionText = questiontext, lAnswers = answerList(questionid) });
}
return PartialView("MultipleChoice", questions);
}
public List<Answers> answerList(int iMyQuestionID)
{
var questionPage = Umbraco.Content(iMyQuestionID);
var answers = new List<Answers>();
foreach(var child in questionPage.Children)
{
answers.Add(new Answers { iAnswerID = child.Id, zAnswerText = child.GetPropertyValue("answerTitle"), bCorrect = child.GetPropertyValue("correctAnswer") });
}
return answers;
}
}
}
最后是我的部分:
@model IEnumerable<ICASolution.Models.MultipleChoiceViewModel>
<div class="ethicsTestContainer">
<div class="col-md-12">
<div class="col-md-12 noRPadding">
@using (Html.BeginUmbracoForm<ICASolution.Controllers.MultipleChoiceSurfaceController>("Grade")) {
foreach (var item in Model)
{
<div class="form-group">
<p><strong>@item.zQuestionTitle</strong></p>
<p>@item.zQuestionText</p>
@{
foreach (var answerItem in item.lAnswers)
{
<div class="radio radio-danger">
@Html.RadioButton(answerItem.iAnswerID.ToString(), answerItem.iAnswerID, new { @type = "radio", @id = answerItem.iAnswerID, @name = item.iQuestionID })
@*<input type="radio" name="@item.iQuestionID" id="@answerItem.iAnswerID" value="option1">*@
<label for="@answerItem.iAnswerID">
@answerItem.zAnswerText <span> </span>@answerItem.bCorrect
</label>
</div>
}
}
</div>
}
<div class="col-sm-8 col-sm-push-2">
<button type="submit" class="btn btn-default btn-block">CLICK HERE TO COMPLETE YOUR ETHICS TEST</button>
</div>
}
</div>
</div>
</div>
向用户显示时一切正常:
但我不知道如何获取用户在 HTTPPOST 上所做的选择(基本上我需要计算他们所做的正确答案的数量)。
您的问题是您在 foreach
循环中为 MultipleChoiceViewModel
生成控件,并生成无法绑定到集合的重复 name
属性(它们不包括索引器) 和重复的 id
个无效属性 html。您需要在 for
循环中生成控件(或使用自定义 EditorTemplate
作为 MultipleChoiceViewModel
类型)
您还需要将 selectedAnswer
属性 移动到 MultipleChoiceViewModel
(不在 selectedAnswer
中)
使用for
循环(模型必须是IList<MultipleChoiceViewModel>
)
for(int i = 0; i < Model.Count; i++)
{
@Html.HiddenFor(m => m[i].iQuestionID) // for post back
@Html.DisplayFor(m => m[i].zQuestionTitle)
...
foreach(var item in Model[i].lAnswers)
{
@Html.RadioButtonFor(m => m[i].selectedAnswer, item.iAnswerID, new { id = item.iAnswerID })
<label for="@item.iAnswerID">@item.zAnswerText</label>
}
}
要使用 EditorTempate
,请在 /Views/Shared/EditorTemplates
中创建一个名为 MultipleChoiceViewModel.cshtml
的局部视图
@model yourAssembly.MultipleChoiceViewModel
@Html.HiddenFor(m => m.iQuestionID)
@Html.DisplayFor(m => m.zQuestionTitle)
...
foreach(var item in Model.lAnswers)
{
@Html.RadioButtonFor(m => m.selectedAnswer, item.iAnswerID, new { id = item.iAnswerID })
<label for="@item.iAnswerID">@item.zAnswerText</label>
}
然后在主视图中,将 for
循环替换为
@Html.EditorFor(m => m)
EditorFor()
方法将根据集合中每个项目的模板生成 html。
旁注:RadioButtonFor()
生成 type="radio"
因此为 @type = "radio"
添加 html 是没有意义的。使用 html helpers
时,切勿覆盖 name
属性
您可以使用以下代码创建单选按钮:
<div class="mt-radio-inline">
<label class="mt-radio">
<input type="radio" name="q1" value="q1_Chart"> Chart
<span></span>
</label>
<label class="mt-radio">
<input type="radio" name="q1" value="q1_AnySize"> Any Size
<span></span>
</label>
</div>
并从下面给出的代码中获取选定的单选按钮值:
string q = form["q1"];
上面的代码形式是FormCollection
的对象
这将为您提供一组所选单选按钮的字符串。
我刚刚涉足 MVC (v4) 的世界,但在获取单选按钮列表列表的实际选定值时遇到了真正的麻烦。我正在从 Umbraco 数据库中提取数据(但我想我尝试做的事情的原理是一样的),其中有问题列表,每个问题都有一个答案列表。我会 post 到目前为止我所做的一切,希望比我更聪明的人能给我指明正确的方向:
这是我的内容结构
我的模型
namespace ICASolution.Models
{
public class MultipleChoiceViewModel
{
public int iQuestionID { get; set; }
public string zQuestionTitle { get; set; }
public string zQuestionText { get; set; }
public List<Answers> lAnswers { get; set; }
}
public class Answers
{
public int iAnswerID { get; set; }
public string zAnswerText { get; set; }
public bool bCorrect { get; set; }
public string selectedAnswer { get; set; }
}
}
我的表面控制器:
namespace ICASolution.Controllers
{
public class MultipleChoiceSurfaceController : SurfaceController
{
//
// GET: /MultipleChoiceSurface/
//public ActionResult Index()
//{
// return PartialView("MultipleChoice", new MultipleChoiceViewModel());
//}
[HttpPost]
public ActionResult Grade(MultipleChoiceViewModel model)
{
return RedirectToCurrentUmbracoPage();
}
public ActionResult Index()
{
var TestPage = Umbraco.Content(CurrentPage.Id);
var questions = new List<MultipleChoiceViewModel>();
foreach (var child in TestPage.Children)
{
var questionid = child.Id;
var questiontitle = child.GetPropertyValue("questionTitle");
var questiontext = child.GetPropertyValue("questionText");
questions.Add(new MultipleChoiceViewModel { iQuestionID = questionid, zQuestionTitle = questiontitle, zQuestionText = questiontext, lAnswers = answerList(questionid) });
}
return PartialView("MultipleChoice", questions);
}
public List<Answers> answerList(int iMyQuestionID)
{
var questionPage = Umbraco.Content(iMyQuestionID);
var answers = new List<Answers>();
foreach(var child in questionPage.Children)
{
answers.Add(new Answers { iAnswerID = child.Id, zAnswerText = child.GetPropertyValue("answerTitle"), bCorrect = child.GetPropertyValue("correctAnswer") });
}
return answers;
}
}
}
最后是我的部分:
@model IEnumerable<ICASolution.Models.MultipleChoiceViewModel>
<div class="ethicsTestContainer">
<div class="col-md-12">
<div class="col-md-12 noRPadding">
@using (Html.BeginUmbracoForm<ICASolution.Controllers.MultipleChoiceSurfaceController>("Grade")) {
foreach (var item in Model)
{
<div class="form-group">
<p><strong>@item.zQuestionTitle</strong></p>
<p>@item.zQuestionText</p>
@{
foreach (var answerItem in item.lAnswers)
{
<div class="radio radio-danger">
@Html.RadioButton(answerItem.iAnswerID.ToString(), answerItem.iAnswerID, new { @type = "radio", @id = answerItem.iAnswerID, @name = item.iQuestionID })
@*<input type="radio" name="@item.iQuestionID" id="@answerItem.iAnswerID" value="option1">*@
<label for="@answerItem.iAnswerID">
@answerItem.zAnswerText <span> </span>@answerItem.bCorrect
</label>
</div>
}
}
</div>
}
<div class="col-sm-8 col-sm-push-2">
<button type="submit" class="btn btn-default btn-block">CLICK HERE TO COMPLETE YOUR ETHICS TEST</button>
</div>
}
</div>
</div>
</div>
向用户显示时一切正常:
但我不知道如何获取用户在 HTTPPOST 上所做的选择(基本上我需要计算他们所做的正确答案的数量)。
您的问题是您在 foreach
循环中为 MultipleChoiceViewModel
生成控件,并生成无法绑定到集合的重复 name
属性(它们不包括索引器) 和重复的 id
个无效属性 html。您需要在 for
循环中生成控件(或使用自定义 EditorTemplate
作为 MultipleChoiceViewModel
类型)
您还需要将 selectedAnswer
属性 移动到 MultipleChoiceViewModel
(不在 selectedAnswer
中)
使用for
循环(模型必须是IList<MultipleChoiceViewModel>
)
for(int i = 0; i < Model.Count; i++)
{
@Html.HiddenFor(m => m[i].iQuestionID) // for post back
@Html.DisplayFor(m => m[i].zQuestionTitle)
...
foreach(var item in Model[i].lAnswers)
{
@Html.RadioButtonFor(m => m[i].selectedAnswer, item.iAnswerID, new { id = item.iAnswerID })
<label for="@item.iAnswerID">@item.zAnswerText</label>
}
}
要使用 EditorTempate
,请在 /Views/Shared/EditorTemplates
中创建一个名为 MultipleChoiceViewModel.cshtml
@model yourAssembly.MultipleChoiceViewModel
@Html.HiddenFor(m => m.iQuestionID)
@Html.DisplayFor(m => m.zQuestionTitle)
...
foreach(var item in Model.lAnswers)
{
@Html.RadioButtonFor(m => m.selectedAnswer, item.iAnswerID, new { id = item.iAnswerID })
<label for="@item.iAnswerID">@item.zAnswerText</label>
}
然后在主视图中,将 for
循环替换为
@Html.EditorFor(m => m)
EditorFor()
方法将根据集合中每个项目的模板生成 html。
旁注:RadioButtonFor()
生成 type="radio"
因此为 @type = "radio"
添加 html 是没有意义的。使用 html helpers
name
属性
您可以使用以下代码创建单选按钮:
<div class="mt-radio-inline">
<label class="mt-radio">
<input type="radio" name="q1" value="q1_Chart"> Chart
<span></span>
</label>
<label class="mt-radio">
<input type="radio" name="q1" value="q1_AnySize"> Any Size
<span></span>
</label>
</div>
并从下面给出的代码中获取选定的单选按钮值:
string q = form["q1"];
上面的代码形式是FormCollection
的对象这将为您提供一组所选单选按钮的字符串。