Asp.net mvc 使控制器从继承的viewmodels中查找属性-测试生成引擎

Asp.net mvc 使控制器从继承的viewmodels中查找属性-测试生成引擎,asp.net-mvc,asp.net-mvc-3,razor,Asp.net Mvc,Asp.net Mvc 3,Razor,在我的项目中,我必须编写测试引擎,它将从文件中读取测试任务,并生成视图,人们将在其中回答: 一个测试有许多任务(任务列表) 有4种类型的任务:单选按钮、复选框、组合框和oneanswer 在视图中,将列出测试中的所有任务 我已经编写了从文件读取并创建视图的部分,但在控制器中接收答案时遇到问题-控制器只查找基本viewModel属性 我是这样做的: Model.cs public enum TaskTypeEnum { RadioButton, CheckBox, ComboBox, On

在我的项目中,我必须编写测试引擎,它将从文件中读取测试任务,并生成视图,人们将在其中回答:

  • 一个测试有许多任务(任务列表)
  • 有4种类型的任务:单选按钮、复选框、组合框和oneanswer
  • 在视图中,将列出测试中的所有任务
  • 我已经编写了从文件读取并创建视图的部分,但在控制器中接收答案时遇到问题-控制器只查找基本viewModel属性

    我是这样做的:

    Model.cs

    public enum TaskTypeEnum
    {
        RadioButton, CheckBox, ComboBox, OneAnswer
    }
    public abstract class TaskModel
    {
        public abstract TaskTypeEnum TaskType { get; }
    
        public string Question { get; set; }
    
        public int TaskId { get; private set; }
    }
    
    public class RadioButtonTaskModel : TaskModel
    {
        public override TaskTypeEnum TaskType { get { return TaskTypeEnum.RadioButton; } }
    
        public List<string> Answers { get; set; }
    
        public string SelectedAnswer { get; set; }
    }
    // Other tasks have different properties than RadioButtonTaskModel
    
    公共枚举任务类型枚举
    {
    单选按钮、复选框、组合框、OneAnswer
    }
    公共抽象类任务模型
    {
    公共抽象任务类型枚举任务类型{get;}
    公共字符串问题{get;set;}
    public int TaskId{get;private set;}
    }
    公共类RadioButtonTaskModel:TaskModel
    {
    公共重写TaskTypeEnum任务类型{get{return TaskTypeEnum.RadioButton;}}
    公共列表答案{get;set;}
    公共字符串SelectedAnswer{get;set;}
    }
    //其他任务的属性与RadioButtonTaskModel不同
    
    ModelController.cs

        public ActionResult SolveTest()
        {
            List<TaskModel> taskList = GetTasksFromFile();
            return View(list);
        }
    
        [HttpPost]
        public ActionResult SolveTest(List<TaskModel> taskList)
        {
            // do something with task list
        }
    
    public ActionResult SolveTest()
    {
    List taskList=GetTasksFromFile();
    返回视图(列表);
    }
    [HttpPost]
    公共行动结果测试(列表任务列表)
    {
    //用任务列表做些什么
    }
    
    SolveTest.cshtml

    @model List<TaskModel>
    
    <h2>SolveTest</h2>
    
    <div>
    @using (Html.BeginForm())
    {
        foreach (var task in Model)
        {
            <div>
                <div>@task.Question</div>
                @if (task.TaskType == TaskTypeEnum.RadioButton)
                {
                    Html.RenderPartial("RadioButtonTaskView", task);
                }
            </div>
        }
        <p>
           <input type="submit" value="Solve" />
        </p>
    }
    </div>
    
    @型号列表
    溶解试验
    @使用(Html.BeginForm())
    {
    foreach(模型中的var任务)
    {
    @任务.问题
    @if(task.TaskType==TaskTypeEnum.RadioButton)
    {
    RenderPartial(“RadioButtonTaskView”,任务);
    }
    }
    
    

    }
    RadioButtonTaskView.cshtml

    @using  MvcApplication2.Models;
    @model RadioButtonTask
    
    <div>
        <ul>
        @foreach (var answer in Model.Answers)
        {
            <li>
                @Html.RadioButtonFor(
                    m => m.SelectedAnswer,
                    answer,
                    new { name = String.Format("taskList[{0}].SelectedAnswer", Model.TaskId) }
                    // it's for making sure, that controller will see that answer as part of list
                    // works fine, when main model is List<RadioButtonTaskModel>
                 );
                @answer
            </li>
        }
        </ul>
    </div>
    
    @使用mvcapapplication2.Models;
    @型号无线电按钮板
    
      @foreach(模型中的var答案。答案) {
    • @Html.radioButton( m=>m.SelectedAnswer, 答复,, 新建{name=String.Format(“任务列表[{0}].SelectedAnswer”,Model.TaskId)} //这是为了确保控制员能在列表中看到答案 //当主模型为列表时,工作正常 ); @答复
    • }
    当然,我删减了一些代码,但我认为这足以理解情况

    问题是,HttpPost SolveTest中的控制器只查找基本任务中包含的属性。如何让他从继承类中查找属性


    或者我完全错了,有一种更容易列出虚拟机的方法?

    您的设计中存在一些固有的缺陷:

  • 如果每页显示多个问题,并且有多个相同类型的问题,您的答案将混合在一起,因为您的答案在每个类型中都具有相同的名称(例如SelectedAnswer)。您需要一个方法来唯一地命名每个输入字段
  • 您的表单是动态的,但是您的SolveTest方法需要静态数量的参数,即使如此,它也不会工作,因为没有称为“任务列表”的字段(至少从您向我们展示的内容来看)。方法上的参数名称必须与HTML中输入字段的名称匹配(即和int SelectedAnswer1)。因此,您需要一种方法来动态地将输入字段连接到任务列表中的对象。要做到这一点,您必须查看FormCollection和/或请求[]

  • 我最近也在寻找同样的解决方案。这里有一个解决您问题的方法:谢谢,这就是我正在寻找的。我忘记了RadioButtonTaskView中名称开头的“任务列表”。现在,当我放入视图列表模型,并在控制器中接收到相同的类型时,我得到了填充列表。但是使用列表我什么也得不到。