Handle Nullable Types with editor template

2019-05-09 01:49发布

问题:

I developed a editor template wich take boolean types and creates a dropdownlist, to changed the true and false default values, into Si and No. Now when I deployed the application i didn't realized that the boolean and Nullable<boolean> are taken like the same and affected for the name of my editor template (boolean.cshtml). Now I don't want this, I want to modify the behavior of the editorfor, only when the datatype of the model was Nullable<boolean> not when it's boolean. How can I handle this???

 @model Nullable<bool>

@{
    var listItems = new[]
    {
        new SelectListItem { Value = "true", Text = "Si" },
        new SelectListItem { Value = "false", Text = "No" }
    };  

}


@Html.DropDownListFor( model => model.Value, listItems)

回答1:

You can't prevent them using the same editor template. But you can handle it within the editor template. You have:

ViewData.ModelMetadata.IsNullableValueType

If you read this article, you can actually see what the default template does with this to switch between two different renderings. Just steal from it:

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html



回答2:

My Views/Shared/EditorTemplates/Boolean.cshtml goes both ways, handling nullable and regular checkboxes.

@model bool?
@{
    if (ViewData.ModelMetadata.IsNullableValueType)
    {
        <text><div class="RB"></text>
        Dictionary<string, object> yesAttrs = new Dictionary<string, object>();
        Dictionary<string, object> noAttrs = new Dictionary<string, object>();
        Dictionary<string, object> nullAttrs = new Dictionary<string, object>();

        yesAttrs.Add("id", ViewData.TemplateInfo.GetFullHtmlFieldId("") + "Yes");
        noAttrs.Add("id", ViewData.TemplateInfo.GetFullHtmlFieldId("") + "No");
        nullAttrs.Add("id", ViewData.TemplateInfo.GetFullHtmlFieldId("") + "NA");


        if (Model.HasValue && Model.Value)
        {
            yesAttrs.Add("checked", "checked");
        }
        else if (Model.HasValue && !Model.Value)
        {
            noAttrs.Add("checked", "checked");
        }
        else
        {
            nullAttrs.Add("checked", "checked");
        }

        @Html.RadioButtonFor(x => x, "true", yesAttrs)
        <label for="@(ViewData.TemplateInfo.GetFullHtmlFieldId(""))Yes">Yes</label>
        @Html.RadioButtonFor(x => x, "false", noAttrs)
        <label for="@(ViewData.TemplateInfo.GetFullHtmlFieldId(""))No">No</label>
        @Html.RadioButtonFor(x => x, "", nullAttrs)
        <label for="@(ViewData.TemplateInfo.GetFullHtmlFieldId(""))NA" class="nostrong" title="Unknown or To Be Determined">tbd</label>
        @:</div>
    }
    else
    {
        ModelState state = ViewData.ModelState[ViewData.ModelMetadata.PropertyName];
        bool value = Model ?? false;
        if (state != null && state.Errors.Count > 0)
        {
            <div class="input-validation-error" style="float: left"></div>
        }
        else
        {
            @Html.CheckBox("", value)
        }
    }
}

Dropdownlists for only 2-3 select items is inconsiderate to users; they require two clicks whereas radio buttons require only one click (unless you don't have the real estate).

When your customers/users haven't made a decision, don't want to make one, don't think you knowing the answer is any of your business, or need to unset true/1/on/positive or false/0/off/negative because neither is accurate, the third option for a Nullable<boolean> can represent To Be Determined (tbd), not set, unknown, or not applicable (n/a).