Joelty
Joelty

Reputation: 2009

Why some properties/fields are being visible in debugger, but not accessible from the code?

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);
        }
    }
}

Upvotes: 2

Views: 2571

Answers (1)

poke
poke

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

Related Questions