简体   繁体   English

ASP.NET MVC处理控制器中动态参数数量的最佳方法

[英]ASP.NET MVC Best way to handle dynamic number of parameters in controller

I have a view model for exams. 我有一个考试的视图模型。 Each exam has an arbitrary number of questions. 每个考试都有一定数量的问题。 It could be 1 question or it could be 50 questions. 这可能是1个问题,也可能是50个问题。 After this gets submitted i need to loop thru the questions and check the answers. 提交后,我需要循环问题并检查答案。 I have a solution but i feel like it's not a best practice. 我有一个解决方案,但我觉得这不是一个最好的做法。

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
        }

Unsure of another way to do this like 不确定另一种方式来做这件事

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult GradeTest(int? testID, string[] questionIDs, string[] answerIDs)

What i'm doing feels a little hacky. 我正在做的事情感觉有点hacky。 Please help OR let me know i'm on the right track. 请帮助或让我知道我在正确的轨道上。 Thanks! 谢谢!

I really don't get the whole context but if this is submitted from a view in a form, then the form is probably built using @Html.TextBoxFor or something like that. 我真的没有得到整个上下文,但如果这是从表单中的视图提交,那么表单可能是使用@ Html.TextBoxFor或类似的东西构建的。 Just take the same model as input to the post Action. 只需将相同的模型作为后期操作的输入。 Please note that any property which is not in a form field will not be included, use HiddenFor if you must have something. 请注意,任何不在表单字段中的属性都不会包含在内,如果您必须拥有某些内容,请使用HiddenFor。 I've put together an example below. 我在下面举了一个例子。

YourViewModel.cs 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 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 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
        }
    }
}

Use a viewmodel with a list. 使用带有列表的viewmodel。 The only caveat to this is binding to a List is somewhat of an advanced technique: Model Binding to a List MVC 4 唯一需要注意的是绑定到List是一种先进的技术: 模型绑定到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)
{
...

I'm a ding dong. 我是一个叮咚。 I was going about this all wrong. 我错了。 I looked up how to pass a collection from view to controller and problem solved! 我查找了如何将视图中的集合传递给控制器​​并解决了问题!

http://www.c-sharpcorner.com/UploadFile/pmfawas/Asp-Net-mvc-how-to-post-a-collection/ http://www.c-sharpcorner.com/UploadFile/pmfawas/Asp-Net-mvc-how-to-post-a-collection/

I updated my view / controller like so: 我像这样更新了我的视图/控制器:

@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++;    
}

and controller: 和控制器:

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult TestDoGrade(int? testID, IEnumerable<TestQuestion> questions, IEnumerable<TestAnswer> answers)
    {

You can accept JObject as parameter. 您可以接受JObject作为参数。 JObject it will make covert form data into List of JProperties that you can enumerate. JObject它会将隐藏的表单数据转换为可以枚举的JProperties列表。

JProperty has two fields, Name and Value. JProperty有两个字段,Name和Value。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM