0

I want to make a day of the week checkbox using a viewModel. Everything is ok on the View, but, if I click submit to save changes, weeklySchedule within my httppost method is null.

Why is weeklySchedule null? How would I send the selected checkbox value to my HttPost action? Any advice would help.

enter image description here

Model:

public class Settings
{
    public class WeeklySetting
    {
        public string DisplayName { get; set; }
        public string Value { get; set; }
        public bool IsChecked { get; set; }
    }
}

View Model:

public class ViewModels
{
    public class Weekly
    {
        public List<Settings.WeeklySetting> Settings { get; set; }
    }
}


public ActionResult CreateWeekly()
   {
       var model = new ViewModels.Weekly
       {
             Settings = new[] 
             {
             new Settings.WeeklySetting{ DisplayName="Monday", Value="MON", IsChecked=false},
             new Settings.WeeklySetting{ DisplayName="Tuesday", Value="TUE", IsChecked=false},
             new Settings.WeeklySetting{ DisplayName="Wednesday", Value="WED", IsChecked=false},
             new Settings.WeeklySetting{ DisplayName="Thursday", Value="THU", IsChecked=false},
             new Settings.WeeklySetting{ DisplayName="Friday", Value="FRI", IsChecked=false},
             new Settings.WeeklySetting{ DisplayName="Saturday", Value="SAT", IsChecked=false},
              new Settings.WeeklySetting{ DisplayName="Sunday", Value="SUN", IsChecked=false},
            }.ToList()
       };
           return View(model);

   }
   [HttpPost]
   public ActionResult CreateWeekly(string submitButton, ViewModels.Weekly weeklySchedule)
   {

    //Do something
       return View("CreateWeekly", weeklySchedule);
   } 

View:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyProject.Controllers.ViewModels.Weekly>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> CreateWeekly </asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<% using (Html.BeginForm()) { %>

  &#60;div&#62;
  &#60;%foreach (var item in Model.Settings)
    {%&#62;

        &#60;%:Html.CheckBoxFor(q=&#62;item.IsChecked) %&#62;
        &#60;%:Html.LabelFor(q=&#62;item.IsChecked,item.DisplayName) %&#62;
        &#60;%:Html.HiddenFor(q=&#62;item.Value) %&#62;
   &#60;% } %&#62;

  &#60;/div&#62;
&#60;br /&#62;
   &#60;input value="GenerateForWeekly" name="submitButton" type="submit" /&#62;
      &#60;%} %&#62;

</asp:Content>

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
loki
  • 2,926
  • 8
  • 62
  • 115

2 Answers2

2

Model binding doesn't work very nicely when you start using foreach() { } loops in your view. If you use an EditorTemplate for WeeklySetting you'll find it works much better as it sorts out all the indices for you.

E.g. (this is MVC3 Razor view syntax)

(1) Create an editor template for WeeklySetting:

@model Settings.WeeklySetting
@Html.CheckBoxFor(m => m.IsChecked)
@Html.LabelFor(m => m.IsChecked,Model.DisplayName)
@Html.HiddenFor(m => m.DisplayName)
@Html.HiddenFor(m => m.Value)

(2) Render in your view with an EditorFor (no foreach):

@using (Html.BeginForm())
{
    <div>
        @Html.EditorFor(m => m.Settings)
    </div>
    <br />
    <input value="GenerateForWeekly" name="submitButton" type="submit" />
}
magritte
  • 7,396
  • 10
  • 59
  • 79
  • but i must use asp.net mvc 3 :( – loki Jul 06 '12 at 11:55
  • 1
    @programmerist My code is for asp.net mvc3, that only difference is that you are using the ASPX view engine instead of the Razor view engine. The principle is the same. – magritte Jul 06 '12 at 12:13
  • Sorry but how to design Editor template – loki Jul 06 '12 at 12:31
  • i wrote my code is the same as your link: coding-in.net/asp-net-mvc-3-how-to-use-editortemplates. i can not see any differences. – loki Jul 06 '12 at 13:11
1

It should work if you use a for loop instead of foreach. As shown here: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx