0

I create a website for my wife. She's a teacher and she would like to have a possibility to create exercises for their students. The case is that she would like to create for instance the following exercise:

Exercise 1: Fill the sentence using a correct word:

  1. My wife is 30 ............. old
  2. I live in this city for 30 .........

I have the following model:

public class Exercise
       {
           [Key]
           public Guid Id { get; set; }

           public string Name { get; set; }

           public string Description { get; set; }

           public ExerciseType Type { get; set; }

           public DifficulityLevel DifficulityLevel { get; set; }

           public List<ExerciseItem> Items { get; set; }

           public DateTime TimeOfCreation { get; set; }

           public DateTime TimeOfModification { get; set; }

       }

public class ExerciseItem
    {
        [Key]
        public Guid Id { get; set; }

        public string Content { get; set; }

        public List<ExerciseItemOption> Options { get; set; }

        public ExerciseItemOption CorrectSelection { get; set; }

    }

I creates a View for my Exercise. I can fill in the basic properties like Name, Description, Difficulity Level and Type. Then I would like to create a button "Add exercise item". When clicked, a partial view (or something else) should be added dynamically where new ExerciseItem can be provided. I've tried to following: I've added a button

@Ajax.ActionLink("Add exercise item", 
                        "AddExerciseItem",
                        "Exercise", new AjaxOptions() { HttpMethod="GET", InsertionMode = InsertionMode.InsertBefore, UpdateTargetId="ExerciseItems"})

and the appropriate div:

<div id="ExerciseItems"></div>

My action method looks as follows:

public ActionResult AddExerciseItem()
        {
            return PartialView("ExerciseItem", new ExerciseItem());
        }

and the partial view:

@model ElangWeb.Models.ExerciseItem
<fieldset>
    <legend>ExerciseItem</legend>

    @Html.HiddenFor(model => model.Id)

    <div class="editor-label">
        @Html.DisplayNameFor(model => model.Content)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Content, new { style = "width:200px" })
    </div>
</fieldset>

It works fine. However when I click button for creating a whole exercise, I do not have ExerciseItem collection in my model:

public ActionResult Create(Exercise exercise)
        {
            using (PersistanceManager pm = new PersistanceManager())
            {
                exercise.Id = Guid.NewGuid();
                exercise.TimeOfCreation = DateTime.Now;
                exercise.TimeOfModification = DateTime.Now;
                pm.ExcerciseRepository.Add(exercise);
            }
            return RedirectToAction("Index");
        }

How should I change the code in order to bind my list of added ExerciseItem objects to my model Exercise?

Community
  • 1
  • 1
niao
  • 4,972
  • 19
  • 66
  • 114

1 Answers1

1

Check out this article about model binding. You basically need to create special names for the exercise items so that they get bound correctly.

e.g. partial:

@model ElangWeb.Models.ExerciseItem
<fieldset>
    <legend>ExerciseItem</legend>
    <label>content</label>
    <input type="hidden" name="ExcersiseItem.Index" value="SomeUniqueValueForThisItem" />
    <input type="text" name="ExcersiseItem[SomeUniqueValueForThisItem].Name" value="@Model.Content" />
</fieldset>    

You can also look at my answer to this question MVC3 Non-Sequential Indices and DefaultModelBinder. Thanks Yarx for finding it, I was actually trying to find it :)

Community
  • 1
  • 1
Bassam Mehanni
  • 14,796
  • 2
  • 33
  • 41