Aspnetcore: DisplayAttribute on nullable variables is lost and ModelMetadata is set to default for variable type

Created on 26 Dec 2019  路  1Comment  路  Source: dotnet/aspnetcore

Describe the bug

When using DisplayAttribute on nullable variables, the ViewData.ModelMetadata is set to default model data for the generic variable type. This leads to any data set to ViewData.ModelMetadata.Name or ViewData.ModelMetadata.Description using DisplayAttribute is nulled.
Sorry if bad description (not sure all the technical terms to properly describe it)

To Reproduce

A model like this will in @Html.EditorFor(m => m) (and the like) loose the ViewData.ModelMetadata.Name and ViewData.ModelMetadata.Description for the nullable Int32 (in this example)

``` C#
public class BugTestModel
{
[Display(Name = "This name is kept in ViewData.ModelMetadata", Description = "This description is kept in ViewData.ModelMetadata")]
public Int32 TestIntOne { get; set; }

    [Display(Name = "This name is nulled in ViewData.ModelMetadata", Description = "This description is nulled in ViewData.ModelMetadata")]
    public Int32? TestIntNull { get; set; }
}

### Further technical details
- ASP.NET Core version 3.1

- Include the output of `dotnet --info`

.NET Core SDK (reflecting any global.json):
Version: 3.1.100
Commit: cd82f021f4

Runtime Environment:
OS Name: Windows
OS Version: 10.0.18363
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.1.100\

Host (useful for support):
Version: 3.1.0
Commit: 65f04fb6db

.NET Core SDKs installed:
3.1.100 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.14 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]

Microsoft.WindowsDesktop.App 3.1.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
```

  • The IDE (VS / VS Code/ VS4Mac) you're running on, and it's version
    Microsoft Visual Studio Community 2019 Version 16.4.2

  • Test project (showing error)
    BugTest.zip

affected-very-few area-mvc bug severity-nice-to-have

Most helpful comment

Thanks @Sausbolle for the detailed repro application. This looks like a bug in MVC's editor template \ display template system. While MVC falls back to using the backing type for nullable types, it ends up reconstructing the ModelMetadata to fit the non-null model type. Essentially, it sees a model metadata instance for a Nullable<int> but has to produce a model metadata for an int model. The transformation erases the metadata.

One workaround you could apply is to specify a template to use for nullable types and point to a template that has a nullable model. For e.g.:

```C#
// Model.cs
[Display(Name = "This name is nulled in ViewData.ModelMetadata", Description = "This description is nulled in ViewData.ModelMetadata")]
[UIHint("NullableInt32")]
public Int32? TestIntNull { get; set; }


```razor
// NullableInt32.cshtml
@model Int32?

...

Parking this in the backlog so we can track fixing this in a later release.

>All comments

Thanks @Sausbolle for the detailed repro application. This looks like a bug in MVC's editor template \ display template system. While MVC falls back to using the backing type for nullable types, it ends up reconstructing the ModelMetadata to fit the non-null model type. Essentially, it sees a model metadata instance for a Nullable<int> but has to produce a model metadata for an int model. The transformation erases the metadata.

One workaround you could apply is to specify a template to use for nullable types and point to a template that has a nullable model. For e.g.:

```C#
// Model.cs
[Display(Name = "This name is nulled in ViewData.ModelMetadata", Description = "This description is nulled in ViewData.ModelMetadata")]
[UIHint("NullableInt32")]
public Int32? TestIntNull { get; set; }


```razor
// NullableInt32.cshtml
@model Int32?

...

Parking this in the backlog so we can track fixing this in a later release.

Was this page helpful?
0 / 5 - 0 ratings