【问题标题】:How to pass List<model> to controller in MVC 4如何将 List<model> 传递给 MVC 4 中的控制器
【发布时间】:2015-12-11 11:00:00
【问题描述】:

我有 2 个模型:问题和答案如下所示,我想发送一个 List 模型到 View,当提交表单时,我将 List 模型提交给控制器,但是在 Action UpdateQuestion 中只能获取问题列表但是答案清单不是。当我提交表单时,你能解释一下并告诉我如何获得每个问题的列表答案

public class Question
    {
        [Key]
        public int Id { get; set; }

        [ForeignKey("QuestionType")]
        public int QuestionTypeId { get; set; }
        public virtual QuestionType QuestionType { get; set; }

        [ForeignKey("Field")]
        public int FieldId { get; set; }
        public virtual Field Field { get; set; }

        public string Brief { get; set; }

        public bool IsGroup { get; set; }

        [ForeignKey("QuestionGroup")]
        public int? QuestionGroupId { get; set; }
        public virtual QuestionGroup QuestionGroup { get; set; }

        public int Priority { get; set; }

        public int Order { get; set; }

        public virtual ICollection<Answer> Answers { get; set; }
    }

和:

public class Answer
    {
        [Key]
        public Int32 Id { get; set; }

        [Column(TypeName = "ntext")]
        [MaxLength]
        public string Content { get; set; }      

        [ForeignKey("Question")]      
        public int QuestionId { get; set; }
        public virtual Question Question { get; set; }      

        public float Mark { get; set; }

        public int Priority { get; set; }    
    }

我有控制器索引来传递要查看的问题列表:

public ActionResult Index()
{
     ApplicationDbContext db = new ApplicationDbContext();
            var listQuestion = db.Questions.ToList();
return View(listQuestion);
}

[HttpPost]

        public ActionResult UpdateQuestion(string submit, List<Question> Questions)
        {
        ...

        return RedirectToAction("Index");
}

在视图中:

@model List<Question>
@{
    int i = 0;
    int j = 0;
}
@using (Html.BeginForm("UpdateQuestion", "TestRoom")) 
{ 
     <ul>
         @foreach(var question in Model)//Question
         {                                
              <li>
              @Html.Hidden("Questions["+i+"].Id", question.Id)
              @{i++;}
              @Html.Raw(question.Brief)
              <ul>
                   @foreach (var answers in question.Answers)
                   {                                            
                        <li>@Html.RadioButton("Questions["+i+"]_Answers["+j+"]",answers.Id)                                                
                                                @Html.Raw(answers.Content)

                                                @{j++;}
                                            </li>
                                        }
                                        @{j = 0;}
                                    </ul>
                                </li>
                            }

                        </ul>
                        <div class="aq-button-panel">
                            <button type="submit" value="Finish" name="submit"><i class="icon-pencil"></i>Submit</button>
                            <button type="submit" value="Back" name="submit">Go Next <i class="icon-arrow-left"></i></button>
                            <button type="submit" value="Next" name="submit">Go Back <i class="icon-arrow-right"></i></button>                        
                        </div>
                    }

【问题讨论】:

    标签: asp.net-mvc-4


    【解决方案1】:

    您的代码存在多个问题。首先,您不能将单选按钮绑定到复杂对象(在您的情况下为Answer,因为单选按钮组仅回发单个值(在您的情况下为所选id 的值id)。接下来您的循环是生成单选按钮组,这些单选按钮组将尝试将所选答案仅绑定到没有意义的第一个答案(您每次将j 的值设置为0)。您的模型需要一个属性来绑定(比如说) int SelectedAnswer.

    首先创建代表您想要在视图中显示/编辑的视图模型(根据需要添加显示和验证属性)

    public class AnswerVM
    {
      public int ID { get; set; }
      public string Content { get; set; }
    }
    public class QuestionVM
    {
      public int ID { get; set; }
      public string Brief { get; set; }
      public int SelectedAnswer { get; set; }
      public IEnumerable<AnswerVM> PossibleAnswers { get; set; }
    }
    

    在您的 get 方法中,获取您的数据模型并映射到视图模型,并将 IEnumerable&lt;QuestionVM&gt; 返回到视图。

    接下来为 typeof QuestionVM (/Views/Shared/EditorTemplates/QuestionVM.cshtml) 创建一个EditorTemplate

    @model QuestionVM
    <li>
      @Html.HiddenFor(m => m.ID)
      @Html.DisplayFor(m => m.Brief)
      <ul>
        @foreach(var answer in Model.PossibleAnswers)
        {
          <li>
            <label>
              @Html.RadioButtonFor(m => m.SelectedAnswer, answer.ID, new { id = "" })
              <span>@answer.Content</span>
            </label>
          </li>
        }
      </ul>
    </li>
    

    在主视图中

    @model IEnumerable<QuestionVM>
    ....
    @Html.BeginForm(...))
    {
      <ul>
        @Html.EditorFor(m => m) // this will generate the correct html for each question in the collection
      </ul>
      <div class="aq-button-panel">
        <button type="submit" ... />
        ...
      </div>
    }
    

    并将 POST 方法更改为

    [HttpPost]
    public ActionResult UpdateQuestion(string submit, IEnumerable<QuestionVM> model)
    

    模型现在包含每个问题的 ID 和每个问题的选定答案的 ID。

    请注意,如果因为ModelState 无效而需要返回视图,则需要重新填充每个问题的PossibleAnswers 属性(您不会为每个@ 中的每个Answer 的每个属性生成表单控件987654338@ - 你也不应该)所以当你提交表单时PossibleAnswers 属性将是一个空集合)

    【讨论】:

    • 非常感谢,我做到了。但是另一个问题,如果一个问题有多个答案。那么你能告诉我,怎么做吗?
    • 在这种情况下,您的AnswerVM 模型将有一个附加属性bool IsSelected,然后为AnswerVM 创建一个EditorTemplate,这将具有ID 的隐藏输入和一个复选框绑定到IsSelected 属性。在QuestionVM 中,将生成单选按钮的@foreach 替换为@EditorFor(m =&gt; m.PossibleAnswers),它现在将为每个答案生成一个复选框。请注意,不再需要 int SelectedAnswer
    • 另一方面,如果您想要不同类型的问题,其中有些是多项选择(即单选按钮),有些只允许文本回答,有些允许是/否回答等,那么您需要一系列不同的视图模型——比如MultipleChoiceQuestionVM、YesNoQuestionVM` 等,然后你的主模型将拥有这些(比如)QuestionaireVM 的集合,其中包含List&lt;MultipleChoiceQuestionVM&gt; 等。
    • 我没有时间为你写申请:)。用您尝试过的代码提出一个新问题,并解释您想要实现的目标和无效的目标。我和其他人将很乐意提供帮助。
    猜你喜欢
    • 1970-01-01
    • 2015-03-05
    • 2012-12-18
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 2022-10-31
    • 2017-03-24
    • 2012-01-11
    相关资源
    最近更新 更多