Reputation: 2009
I'm curious, why I cannot access Attributes
from the code, but it's perfectly visible in debugger?
Also seems like there's no property/field called "Attributes"
Error:
'ModelMetadata' does not contain a definition for 'Attributes' and no accessible extension method 'Attributes' accepting a first argument of type 'ModelMetadata' could be found (are you missing a using directive or an assembly reference?)
Code:
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using System;
using System.Linq.Expressions;
namespace Project.Views
{
public static class HtmlExtensions
{
public static IHtmlContent DescriptionFor<TModel, TValue>(this IHtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
if (html == null) throw new ArgumentNullException(nameof(html));
if (expression == null) throw new ArgumentNullException(nameof(expression));
var modelExplorer = ExpressionMetadataProvider.FromLambdaExpression(expression, html.ViewData, html.MetadataProvider);
if (modelExplorer == null) throw new InvalidOperationException($"Failed to get model explorer for {ExpressionHelper.GetExpressionText(expression)}");
var resolvedDisplayName = modelExplorer.Metadata.Attributes ?? modelExplorer.Metadata.PropertyName;
return new HtmlString(resolvedDisplayName ?? string.Empty);
}
}
}
Upvotes: 2
Views: 2571
Reputation: 387775
The ModelExplorer.Metadata
property that you are accessing has the type ModelMetadata
. If you look at that type, you will see that it does not have an Attributes
member that you could access.
However, the runtime type of the object that sits at modelExplorer.Metadata
is the type DefaultModelMetadata
which does have an Attributes
member.
Since the debugger only cares about runtime types, you are able to access that property. But when you attempt to do it in code, you are limited by the compile time types. You would have to cast the type first in order to access the Attributes
property:
ModelMetadata metadata = modexlExplorer.Metadata;
// metadata.Attributes does not exist
DefaultModelMetadata defaultMetadata = (DefaultModelMetadata) metadata;
// defaultMetadata.Attributes exists
Upvotes: 4