I am using the twitter bootstrap framework, so to get the EditorFor and DisplayFor methods to output what I need, I created custom templates for each of the types like string, text, password etc. For my login page I want a RememberMe bool, so as before, I created the following template and put in in Boolean.cshtml:
@model bool
<div class="control-group">
<div class="controls">
<label class="checkbox">
@Html.CheckBoxFor(m => m, new {@class = "checkbox"})
@Html.LabelFor(m => m)
</label>
</div>
</div>
Pretty simple, but when I use:
@Html.EditorFor(m => m.RememberMe)
I get an exception saying the value being bassed cannot be null:
The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type 'System.Boolean'.
What am I missing? Seems like it should be straight forward. The field on the model object looks like follows:
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
Thanks.
UPDATE: So it seems that in the end it's a matter of creating an empty view model object and passing it to the view instead of letting MVC create one on it's own.
I would not do it that way. If the value can be null, I would make sure that your editor template has nullable boolean as the model type. So your editor template (in Views\Shared\EditorTemplates\Boolean.cshtml) would be:
@model Boolean?
@Html.CheckBox("", Model.HasValue && Model.Value)
And then in the razor of your main view, you could have:
<div class="control-group">
<div class="controls">
<label class="checkbox">
@Html.EditorFor(m => m, new {@class = "checkbox"})
@Html.LabelFor(m => m)
</label>
</div>
</div>
Reading the responses so far, I started wondering about how the model object was being initialized. So this is rather weird, but I found the answer. Hopefully someone can explain the weirdness. Might be how MVC initializes a model object if you don't specify one.
The default MVC Internet template has the following for the Login action:
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
That gives the error. Changing it to the following however, fixes the problem:
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
var loginModel = new LoginModel();
ViewBag.ReturnUrl = returnUrl;
return View(loginModel);
}
So this answers the question on how to solve the problem, but still leaves the reason unresolved. Could it be because MVC creates an instance of the object in a different way, say with reflection or something?
You could change your model so it accepts the null values as "yes"/"no"
public bool? RememberMe { get; set; }
You have to initialize your RememberMe
bool value
inside the constructor as shown below.
Remember that using uninitialized variables in C# is not allowed.
using System.ComponentModel;
public class ClassName
{
public ClassName ()
{
RememberMe = false;
}
[DefaultValue(false)]
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
For more infromation check Default Values Table
I hope this will help to you.