简体   繁体   中英

How to access inherited attributes of a property in a partial class?

I have the following classes:

interface IEntityWithId
{
    int id { get; set; }
}

public class MyEntityMetaData
{
    [Display(Name="Name of my property")]
    public string MyProp { get; set; }
}

public partial class MyEntity : MyEntityMetaData, IEntityWithId
{
}

/* Autogenerated code somewhere else */
public partial class MyEntity
{
    public int Id { get; set; }
    public string MyProp { get; set; }
}

Now I have a IQueryable<IEntityWithId> in which the objects are actually of type MyEntity .

I used this code to extract display names:

private static List<string> GetColumnNames<T>(IQueryable<T> query) where T : class
{
    Type elementType = query.ElementType;
    var defaultColumns = new List<WebGridColumn>();
    var columnNames =
    (
        from
            p in elementType.GetProperties()
        where
           IsBindableType(p.PropertyType) &&
           (p.GetIndexParameters().Length == 0)

        select
        new
        {
            DisplayName = (DisplayNameAttribute)p.GetCustomAttributes(typeof(DisplayNameAttribute), true).FirstOrDefault(),
            Display = (DisplayAttribute)p.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault(),
            Name = p.Name
        }
    ).Select
    (
        name =>
        name.DisplayName != null ?
        name.DisplayName.DisplayName :
        name.Display != null ?
        name.Display.Name :
        name.Name
    ).ToList();
    return columnNames;
}

But it doesn't actually work (display names are null). I do get correct type and properties within the method, but the attributes are missing. I'm guessing it has something to do with the fact that those are attributes of a parent class and/or my class being a partial one.

Is there something I can do to actually get those attributes inside my method (I can't really change my input type)?

Edit: Having run into the problem yet again, I believe that the answer to this question is in the part of MVC code responsible for bringing ViewData.ModelMetadata to life (because ViewData.ModelMetadata has correct those display names, even when they are as oddly inherited as in this question). This post makes me believe that this part of MVC that I'm looking for is a ModelMetadataProvider . One of those days I'll have to analyze the code...

The autogenerated code is hiding MyEntityData.MyProp with MyEntity.Prop . MyEntity.Prop is to all efects a completely new method and does not inherit any attributes that might be defined in MyEntityData.MyProp .

If possible, you should refactor MyEntityData to:

public class MyEntityMetaData
{
    [Display(Name="Name of my property")]
    public virtual string MyProp { get; set; }
}

And make the code generation tool override said method:

/* Autogenerated code somewhere else */
public partial class MyEntity
{
    public int Id { get; set; }
    public override string MyProp { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM