6

Referencing the answer in this post I added /Views/Shared/DisplayTemplates and added a partial view called ShortDateTime.cshtml as shown below:

@model System.DateTime
@Model.ToShortDateString()

When the model contains a value this works and the formatted date is displayed correctly:

@Html.DisplayFor(modelItem => item.BirthDate, "ShortDateTime")

However, if a null value is returned a 'System.InvalidOperationException' is thrown. Indicating:

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

My first inclination was to use an if statement inside the partial view but it didn't seem to matter. Without referencing the template null values are handled as in:

@Html.DisplayFor(modelItem => item.BirthDate)

but the original issue of formatting remains. When I try to put conditional formatting in the View as follows, it doesn't work but I hoping it's just a syntax thing.

@Html.DisplayFor(modelItem => item.BirthDate == null) ? string.Empty : (modelItem => item.BirthDate, "ShortDateTime"))

The above results in a different 'System.InvalidOperationException':

{"Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions."}

So, is there a way to do conditional formatting in the View to generate just the date from a DateTime value?

Community
  • 1
  • 1
Greg Hayden
  • 135
  • 1
  • 3
  • 12

4 Answers4

4

The problem you're experiencing is that you are passing a null value into a non-nullable model. Change the partial view's model to DateTime?. For example:

@model DateTime?          
@if (!Model.HasValue)
    {
    <text></text>
}
else
{
    @Model.Value.ToShortDateString()
}

Hope this helps.

Vinney Kelly
  • 4,975
  • 1
  • 25
  • 31
  • 1
    Unfortunately System.DateTime does not contain a definition for HasValue. – Greg Hayden Nov 12 '13 at 17:33
  • 2
    Greg, notice that I changed the model type to a nullable DateTime or `DateTime?`. This is where the `HasValue` method comes from. – Vinney Kelly Nov 12 '13 at 19:31
  • Also, I should mention that the nullable DateTime model type is capable of receiving a non-nullable DateTime. So there's no need to create another version of your partial view for handling non-nullable DateTime values. Lastly, I did set up a small test last night to be certain that the code I've given you above is correct and functional. If you paste the code into your ShortDateTime partial view, you should instantly stop receiving the errors your originally reported. From there, you can modify the format of the DateTime by replacing `ToShortDateString()` with whatever format you'd like. – Vinney Kelly Nov 12 '13 at 19:51
  • 1
    @Vinney 's answer worked for me and should be marked as the answer. – Walter de Jong Mar 07 '17 at 23:34
  • Thanks, @WalterdeJong! I second that. :) – Vinney Kelly Jun 14 '17 at 15:31
1

Have you tried this?

@if (modelItem.BirthDate != null) { Html.DisplayFor(modelItem => item.BirthDate, "ShortDateTime") }
Wagner DosAnjos
  • 6,304
  • 1
  • 15
  • 29
  • Didn't quite work but certainly put me on the right path and it was just an issue of syntax from there as shown below. Thanks. – Greg Hayden Nov 12 '13 at 17:39
0

I guess you should declare the BirthDate property as nullable in model class

public DateTime? BirthDate{ get; set; }

and you must have declared as

public DateTime BirthDate{ get; set; }

this will expect a value every time.

if you set as nullable it will not expect a value.

abc123
  • 262
  • 4
  • 27
  • Thanks, but the fields are in code generated by EF and regeneration would impose additional maintenance. And yes I suppose I could use a partial class but sometimes you just need to get-her-done. – Greg Hayden Nov 12 '13 at 17:42
0

By applying the conditional statement ahead of the Html helper, only non null values get passed.

@if (item.BirthDate != null) { @Html.DisplayFor(modelItem => item.BirthDate , "ShortDateTime")}
Greg Hayden
  • 135
  • 1
  • 3
  • 12