Dynamic MVC Model

Consider a dynamic survey form consisting of n questions , and for each question there can be n answers

<form>
<!-- Question block -->
    <input id="QuestionText" name="QuestionText" placeholder="Text otázky" value="" type="text">
    <table>
        <!-- Answer block -->
        <tr><td><input name="AnswerIsCorrect" type="checkbox"></td>
            <td><input name="AnswerText" type="text"></td>
        </tr>
        <!-- Answer block END -->
        <tr><td><input name="AnswerIsCorrect" type="checkbox"></td>
            <td><input name="AnswerText" type="text"></td>
        </tr>
        <!-- More answers -->
    </table>
    <input id="QuestionComment" type="text">
    <!-- Question block END -->

    <!-- More questions -->
</form>

Is it possible for MVC to parse it when sent to a similar structure:

public  class CreateSurveyModel
{
    public List<QuestionModel> Questions { get; set; }
}
public class QuestionModel
{
    public string QuestionText { get; set; }
    public string QuestionComment { get; set; }
    public List<AnswerModel> Answers { get; set; }
}
public class AnswerModel
{
    public string AnswerText { get; set; }
    public bool IsCorrect { get; set; }
}

If so, how?

EDIT (as indicated in the answers):

@using(Html.BeginForm("Send", "Try", FormMethod.Post/*or FormMethod.Get*/))
{
    foreach(var question in Model.Questions)
    {
        <!-- Question block -->

         @Html.TextBox("QuestionText", question.QuestionText)            
         <table>
             @foreach(var answer in question.Answers)
             {
                 <!-- Answer block -->
                 <tr>
                     <td>@Html.CheckBox("AnswerIsCorrect", answer.IsCorrect)</td>
                     <td>@Html.TextBox("AnswerText", answer.AnswerText )</td>
                 </tr>
                 <!-- Answer block END -->
             }
         </table>
         @Html.TextBox("QuestionComment", question.QuestionComment)
         <!-- Question block END -->
    }
    <input type="submit"/>
}

And the action:

[HttpPost]
public ActionResult Send(CreateSurveyModel model)
{
    return Index();
}

But model.Questions is null

+3
source share
2 answers

In your view, use the following structure:

@using (Html.BeginForm())
{
    for (int i = 0; i < Model.Questions.Count(); i++)
    {
        @Html.TextBoxFor(model => model.Questions[i].QuestionText, new { placeholder = "Text otázky" })
        <table>
            @for (int j = 0; j < Model.Questions[i].Answers.Count(); j++)
            {
                <!-- Answer block -->
                <tr>
                    <td>@Html.CheckBoxFor(model => model.Questions[i].Answers[j].IsCorrect)</td>
                    <td>@Html.TextBoxFor(model => model.Questions[i].Answers[j].AnswerText)</td>
                </tr>
            }
        </table>
        @Html.TextBoxFor(model => model.Questions[i].QuestionComment)
        <!-- Question block END -->
    }
    <input type="submit"/>
}

This code should help you fill out the view correctly, and also pass the model to the view correctly.

Update

You can test the following actions:

public ActionResult Send()
{
    CreateSurveyModel model = new CreateSurveyModel();
    model.Questions = new List<QuestionModel>()
    {
        new QuestionModel()
        {
            QuestionText = "1",
            QuestionComment = "Comment 1",
            Answers = new List<AnswerModel>()
            {
                new AnswerModel()
                {
                    AnswerText = "A1",
                    IsCorrect = false,
                },
                new AnswerModel()
                {
                    AnswerText = "A2",
                    IsCorrect = true,
                },
                new AnswerModel()
                {
                    AnswerText = "A3",
                    IsCorrect = false,
                },
                new AnswerModel()
                {
                    AnswerText = "A4",
                    IsCorrect = true,
                },
            }
        },
        new QuestionModel()
        {
            QuestionText = "2",
            QuestionComment = "Comment 2",
            Answers = new List<AnswerModel>()
            {
                new AnswerModel()
                {
                    AnswerText = "A5",
                    IsCorrect = false,
                },
                new AnswerModel()
                {
                    AnswerText = "A6",
                    IsCorrect = false,
                },
                new AnswerModel()
                {
                    AnswerText = "A7",
                    IsCorrect = false,
                },
                new AnswerModel()
                {
                    AnswerText = "A8",
                    IsCorrect = true,
                },
                new AnswerModel()
                {
                    AnswerText = "A9",
                    IsCorrect = false,
                },
            }
        }
    };

    return View(model);
}

[HttpPost]
public ActionResult Send(CreateSurveyModel model)
{
    return View();
}

. , .

+1

:

@using(Html.BeginForm("action", "controller", FormMethod.Post/*or FormMethod.Get*/))
{
    foreach(var question in Model.Questions)
    {
         <!-- Question block -->
         @Html.TextBoxFor("QuestionText", question.QuestionText)            
         <table>
             @foreach(var answer in question.Answers)
             {
                 <!-- Answer block -->
                 <tr>
                     <td>@Html.Checkbox("AnswerIsCorrect", answer.IsCorrect)</td>
                     <td>@Html.TextBox("AnswerText", answer.AnswerText )</td>
                 </tr>
                 <!-- Answer block END -->
             }
         </table>
         @Html.TextBox("QuestionComment", question.QuestionComment)
         <!-- Question block END -->
    }
}
0

All Articles