2

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"

ModelMetadata Class

enter image description here

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);
        }
    }
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Joelty
  • 1,751
  • 5
  • 22
  • 64
  • 2
    It would be awesome if you could provide a [mcve]. If I had to _guess_, it would be that the type that inherits from the abstract base class has extra properties. The code let's you access the properties available from the type of the **variable**. The debugger shows all properties for the **object** (which may be broader than the type of the variable). – mjwills Mar 27 '19 at 09:35
  • Yea, I'm about to. Anyway, thanks to both you & @poke – Joelty Mar 27 '19 at 09:40

1 Answers1

4

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
poke
  • 369,085
  • 72
  • 557
  • 602