Создание контроллера для поиска свойств от наследования viewmodels - Test Making Engine - PullRequest
0 голосов
/ 22 февраля 2012

В моем проекте мне нужно написать тестовый движок, который будет читать тестовые задачи из файла, и создавать представление, где люди будут отвечать:

  1. Один тест имеет много задач (список задач).
  2. Существует 4 типа задач: радиокнопка, флажок, поле со списком, один ответ.
  3. В списке будут перечислены все задачи из теста.

У меня естьнаписанная часть, которая читает из файла и создает представление, но у меня проблемы с получением ответов в контроллере - контроллер ищет только базовые свойства 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

ModelController.cs

    public ActionResult SolveTest()
    {
        List<TaskModel> taskList = GetTasksFromFile();
        return View(list);
    }

    [HttpPost]
    public ActionResult SolveTest(List<TaskModel> taskList)
    {
        // do something with task list
    }

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>

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>

Я вырезал некоторый код, изКонечно, но я думаю, что этого достаточно, чтобы понять, какова ситуация.

Проблема в том, что контроллер в HttpPost SolveTest ищет только свойства, которые содержатся в базовой задаче.Как заставить его искать свойства унаследованных классов?

Или, может быть, я делаю это совершенно неправильно, и есть более простой способ составить список виртуальных машин?

1 Ответ

0 голосов
/ 22 февраля 2012

В вашем дизайне есть некоторые недостатки:

  1. Если вы отображаете более одного вопроса на странице, а у вас более одного и того же типа, ваш ответ будет смешан вместетак как ваши будут иметь одинаковые имена для каждого типа (например, SelectedAnswer).Вам нужен метод для уникального именования каждого поля ввода.
  2. Ваша форма является динамической, но ваш метод SolveTest ожидает статическое число параметров, и даже при этом он никогда не будет работать, так как нет поля(по крайней мере из того, что вы показали нам) называется "taskList".Имена параметров в методе должны совпадать с именами полей ввода в HTML (т. Е. И int SelectedAnswer1).Поэтому вам понадобится способ динамического подключения полей ввода к объектам в вашем списке задач.Для этого вам нужно взглянуть на FormCollection и / или Request [], чтобы сделать это.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...