简体   繁体   中英

Working with Nullable DateTime in Custom EditorFor

I am trying to create a custom editor for my ASP.NET MVC5 pages, but when the property TProp in the example below is a Nullable<DateTime> I receive an error. The failure seems to happen on helper.EditorFor(Property) . Here is the error:

The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type 'System.DateTime'.

Here is the code:

public static IHtmlString CustomEditorFor<TModel, TProp>(this HtmlHelper<TModel> helper,
    Expression<Func<TModel, TProp>> property)
{
    var htmlString =
        "<div class=\"form-group\">" +
            helper.LabelFor(property) +
            "<div class=\"col-md-10\">" +
                helper.EditorFor(property) +
                helper.ValidationMessageFor(property) +
            "</div>" +
        "</div>"
        ;
    return new HtmlString(htmlString);
}

EDIT: Adding Code reference code for for view, viewmodel and editor template

View : Code that is attempting to render the viewmodel's values

@model MyApp.Web.ViewModels.ProductViewModel

<div class="panel panel-primary">
    <div class="panel-heading">Upgrade Details</div>
    <div class="panel-body">
        <div class="form-horizontal">
            @Html.CustomEditorFor(model => model.DateUpgraded)
        </div>
    </div>
</div>

Viewmodel : this is the Nullable<DateTime> property that is not rendering

public Nullable<DateTime> DateUpgraded { get; set; }

EditorTemplate : editor template for DateTime

@model DateTime
@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
        new { @class = "form-control", placeholder = ViewData.ModelMetadata.Watermark })

The error is thrown because you created a custom EditorTemplate for DateTime which is called by your helper.EditorFor(property) in your extension method. This passes a model of Nullable<DateTime> to a view which expects a model which is DateTime (not nullable).

You can solve the issue by changing the declaration in the template to

@model DateTime? // nullable

However, using both an extension method which calls an EditorTemplate for a simple value type makes little sense and you should be using one or the other.

Using the extension method, your code would be (note this uses the recommended TagBuilder class for generating html)

public static IHtmlString CustomEditorFor<TModel, TProp>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProp>> property)
{
    var name = ExpressionHelper.GetExpressionText(property);
    var metadata = ModelMetadata.FromLambdaExpression(property, helper.ViewData);
    var formatString = metadata.DisplayFormatString;
    var watermark = metadata.Watermark;

    StringBuilder html = new StringBuilder();
    html.Append(helper.TextBoxFor(property, formatString, new { @class = "form-control", placeholder = watermark }));
    html.Append(helper.ValidationMessageFor(property));
    TagBuilder container = new TagBuilder("div");
    container.AddCssClass("col-md-10");
    container.InnerHtml = html.ToString();
    html = new StringBuilder();
    html.Append(helper.LabelFor(property));
    html.Append(container.ToString());
    container = new TagBuilder("div");
    container.AddCssClass("form-group");
    container.InnerHtml = html.ToString();
    return MvcHtmlString.Create(container.ToString());   
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM