ASP.NET MVC 在控制器中处理动态参数数量的最佳方式
ASP.NET MVC Best way to handle dynamic number of parameters in controller
我有一个用于考试的视图模型。每个考试都有任意数量的问题。可以是 1 个问题,也可以是 50 个问题。提交后,我需要遍历问题并检查答案。我有一个解决方案,但我觉得这不是最佳做法。
int questionNumber = 1;
while (Request.Form["Question" + questionNumber.ToString()] != null)
{
int questionID = Convert.ToInt32(Request.Form["Question" + questionNumber.ToString()]);
int answerID = Convert.ToInt32(Request.Form["Answer" + questionNumber.ToString()]);
//TODO: Check if answer is correct
}
不确定像这样的另一种方法
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult GradeTest(int? testID, string[] questionIDs, string[] answerIDs)
我正在做的事情感觉有点老套。请帮助或让我知道我在正确的轨道上。谢谢!
使用带有列表的视图模型。唯一需要注意的是绑定到列表是一种高级技术:Model Binding to a List MVC 4
public class Response {
public string QuestionId {get;set;}
public string AnswerId {get;set;}
}
public class ExamViewModel {
public int? TestId {get;set;}
public List<Response> Responses {get;set;}
}
public ActionResult GradeTest(ExamViewModel viewModel)
{
...
我真的不了解整个上下文,但如果这是从表单中的视图提交的,那么表单可能是使用 @Html.TextBoxFor 或类似的东西构建的。只需采用与 post 操作输入相同的模型。请注意,任何不在表单字段中的 属性 都不会被包括在内,如果你必须有一些东西,请使用 HiddenFor 。我在下面整理了一个示例。
YourViewModel.cs
public class YourViewModel {
public int ExamID { get; set; }
public string Name { get; set; }
public List<int> QuestionIDs { get; set; }
public List<int> AnswerIDs { get; set; }
}
YourView.cshtml
@model YourViewModel.cs
using(Html.BeginForm("PostExam", "YourController", FormMethod.Post)
{
@Html.HiddenFor(m => m.ExamID)
@Html.AntiForgeryToken()
<strong>Please enter your name</strong>
@Html.TextBoxFor(m => m.Name)
@*Your question and answers goes here*@
<input type="submit" value="Hand in" />
}
YourController.cs
public class YourController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken()]
public ActionResult PostExam(YourViewModel Submitted)
{
//Handle submitted data here
foreach(var QuestionID in Submitted.QuestionIDs)
{
//Do something
}
}
}
我是叮咚。我的想法全错了。我查找了如何将集合从视图传递到控制器并解决了问题!
http://www.c-sharpcorner.com/UploadFile/pmfawas/Asp-Net-mvc-how-to-post-a-collection/
我像这样更新了我的视图/控制器:
@foreach (var question in Model.TestQuestions)
{
@Html.Hidden("Questions[" + questionIndex.ToString() + "].ID", question.ID)
<h3>@question.Text</h3>
<section>
@foreach (var answer in question.TestAnswers)
{
<div>
@Html.RadioButton("Answers[" + questionIndex.ToString() + "].ID", answer.ID) @answer.Text
</div>
}
</section>
<hr />
questionIndex++;
}
和控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult TestDoGrade(int? testID, IEnumerable<TestQuestion> questions, IEnumerable<TestAnswer> answers)
{
您可以接受 JObject 作为参数。 JObject 它会将隐蔽的表单数据放入您可以枚举的 JProperties 列表中。
JProperty 有两个字段,名称和值。
我有一个用于考试的视图模型。每个考试都有任意数量的问题。可以是 1 个问题,也可以是 50 个问题。提交后,我需要遍历问题并检查答案。我有一个解决方案,但我觉得这不是最佳做法。
int questionNumber = 1;
while (Request.Form["Question" + questionNumber.ToString()] != null)
{
int questionID = Convert.ToInt32(Request.Form["Question" + questionNumber.ToString()]);
int answerID = Convert.ToInt32(Request.Form["Answer" + questionNumber.ToString()]);
//TODO: Check if answer is correct
}
不确定像这样的另一种方法
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult GradeTest(int? testID, string[] questionIDs, string[] answerIDs)
我正在做的事情感觉有点老套。请帮助或让我知道我在正确的轨道上。谢谢!
使用带有列表的视图模型。唯一需要注意的是绑定到列表是一种高级技术:Model Binding to a List MVC 4
public class Response {
public string QuestionId {get;set;}
public string AnswerId {get;set;}
}
public class ExamViewModel {
public int? TestId {get;set;}
public List<Response> Responses {get;set;}
}
public ActionResult GradeTest(ExamViewModel viewModel)
{
...
我真的不了解整个上下文,但如果这是从表单中的视图提交的,那么表单可能是使用 @Html.TextBoxFor 或类似的东西构建的。只需采用与 post 操作输入相同的模型。请注意,任何不在表单字段中的 属性 都不会被包括在内,如果你必须有一些东西,请使用 HiddenFor 。我在下面整理了一个示例。
YourViewModel.cs
public class YourViewModel {
public int ExamID { get; set; }
public string Name { get; set; }
public List<int> QuestionIDs { get; set; }
public List<int> AnswerIDs { get; set; }
}
YourView.cshtml
@model YourViewModel.cs
using(Html.BeginForm("PostExam", "YourController", FormMethod.Post)
{
@Html.HiddenFor(m => m.ExamID)
@Html.AntiForgeryToken()
<strong>Please enter your name</strong>
@Html.TextBoxFor(m => m.Name)
@*Your question and answers goes here*@
<input type="submit" value="Hand in" />
}
YourController.cs
public class YourController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken()]
public ActionResult PostExam(YourViewModel Submitted)
{
//Handle submitted data here
foreach(var QuestionID in Submitted.QuestionIDs)
{
//Do something
}
}
}
我是叮咚。我的想法全错了。我查找了如何将集合从视图传递到控制器并解决了问题!
http://www.c-sharpcorner.com/UploadFile/pmfawas/Asp-Net-mvc-how-to-post-a-collection/
我像这样更新了我的视图/控制器:
@foreach (var question in Model.TestQuestions)
{
@Html.Hidden("Questions[" + questionIndex.ToString() + "].ID", question.ID)
<h3>@question.Text</h3>
<section>
@foreach (var answer in question.TestAnswers)
{
<div>
@Html.RadioButton("Answers[" + questionIndex.ToString() + "].ID", answer.ID) @answer.Text
</div>
}
</section>
<hr />
questionIndex++;
}
和控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult TestDoGrade(int? testID, IEnumerable<TestQuestion> questions, IEnumerable<TestAnswer> answers)
{
您可以接受 JObject 作为参数。 JObject 它会将隐蔽的表单数据放入您可以枚举的 JProperties 列表中。
JProperty 有两个字段,名称和值。