MVC 4 Custom template for bool (razor)

2019-03-18 05:03发布

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.

4条回答
趁早两清
2楼-- · 2019-03-18 05:25

You could change your model so it accepts the null values as "yes"/"no"

public bool? RememberMe { get; set; }
查看更多
【Aperson】
3楼-- · 2019-03-18 05:26

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.

查看更多
干净又极端
4楼-- · 2019-03-18 05:39

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?

查看更多
Viruses.
5楼-- · 2019-03-18 05:45

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>
查看更多
登录 后发表回答