In my project I have to write the test engine, which will read test tasks from file, and make view, where people will answer:
- One test has many tasks (list of tasks).
- There are 4 types of tasks: radiobutton, checkbox, combobox, oneanswer.
- In view all tasks from test will be listed.
I've written part which reads from file and creates view, but I have problems with receiving answers in controller - controller only looks for base viewModel properties.
I made it like this:
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>
I cut some code, of course, but I think it's enough to understand what is the situation.
The problem is, that Controller in HttpPost SolveTest is looking only for properties which are contained in base Task. How to make him to look for the properties from inheriting classes?
Or maybe I am doing it completely wrong, and there is a easier way to make list of VMs?