Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Changes to property ModelMetadata provided by a ModelMetadataDetailsProvider are lost for Nullable<T> in Display/Edit templates when DataType is used to change the template #4116

Closed
@rwasef1830

Description

@rwasef1830

Hello ASP.net team,
This bug is related to #2539, but the fix for that bug doesn't work when the nullable property has a DataType attribute that changes the display / edit templates.

protected ViewDataDictionary(ViewDataDictionary source, object model, Type declaredModelType)
            : this(...)
        {
            // ...

            // This is the core constructor called when Model is known.
            var modelType = GetModelType(model);
            var metadataModelType = source.ModelMetadata.UnderlyingOrModelType;
            if (modelType == metadataModelType && model == source.ModelExplorer.Model)
            {
                // Preserve any customizations made to source.ModelExplorer.ModelMetadata if the Type
                // that will be calculated in SetModel() and source.Model match new instance's values.
                ModelExplorer = source.ModelExplorer;
            }
            else if (model == null)
            {
                // Ensure ModelMetadata is never null though SetModel() isn't called below.
                ModelExplorer = _metadataProvider.GetModelExplorerForType(_declaredModelType, model: null);
            }

            // If we're constructing a ViewDataDictionary<TModel> where TModel is a non-Nullable value type,
            // SetModel() will throw if we try to call it with null. We should not throw in that case.
            if (model != null)
            {
                SetModel(model);
            }
        }

The main part of that fix was this part:

var modelType = GetModelType(model);
var metadataModelType = source.ModelMetadata.UnderlyingOrModelType;
if (modelType == metadataModelType && model == source.ModelExplorer.Model) { ... }

I suspect that the code does not handle nullable types correctly because metadataModelType will never be Nullable<T> whereas modelType can be, so the ModelExplorer is being always discarded in case of nullable properties.

https://github.com/rwasef1830/aspnet-mvc6-modelmetadata-repro

Hope that helps.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions