DataAnnotations MetadataType not working

3.3k views Asked by At

I'm not being able to attach a MetadataType to a auto generated class in our application. I tested setting the Order attribute in the generated class and it works fine, but if try to use another class i cannot get the attributes later.

I also already tried the solution suggested here with no success.

Generated class

[Table(Name = "T_MKT_Product")]
public partial class T_MKT_Product : GlobalSist.DataAccess.Base.BaseEntity
{
    [Column(Storage = "_code", DbType = "varchar(20)", IsUnique = true)]
    public virtual string Code
    {
        get { return _code; }
        set
        {
            if (_code != value)
            {
                OnPropertyChanging("Code");
                _code = value;
                OnPropertyChanged("Code");
            }
        }
    }

    [Column(Storage = "_name", DbType = "varchar(200)")]
    public virtual string Name
    {
        get { return _name; }
        set
        {
            if (_name != value)
            {
                OnPropertyChanging("Name");
                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }

    [Column(Storage = "_description", DbType = "varchar(200)", CanBeNull = true)]
    public virtual string Description
    {
        get { return _description; }
        set
        {
            if (_description != value)
            {
                OnPropertyChanging("Description");
                _description = value;
                OnPropertyChanged("Description");
            }
        }
    }
}

Then i defined the following classes

[MetadataType(typeof(ProductMetaData))]
public partial class T_MKT_Product
{
}

public class ProductMetaData
{
    [Display(Order = -1)]
    public virtual string Code { get; set; }

    [Display(Order = -2)]
    public object Name { get; set; }

    [Display(Order = -3)]
    public object Description { get; set; }
}

Help! :)

2

There are 2 answers

1
Francesco Abbruzzese On BEST ANSWER

Attribute.IsDefined(currentProp, typeof(DisplayAttribute))is still False IT MUST BE FALSE. Probably you are checking the Order with a custom code! The answer to your problem is very easy: your custom code is simply WRONG. Probably it is wrong because you pretend to find the attribute added with the methadata class together with all other "native" attributes of the class. THIS IS WRONG! .Net Clr HAS NO NATIVE SUPPORT FOR MetaDataType Attribute! IT IS JUST A CONVENTION. It is up to you, verifyng that your class has a MetaDataType and retrieving also the attributes of the MetaDataType with the same name of the properties of your original class. I MEAN YOU HAVE TO DO THIS JOB MANUALLY. All Attributes that the Mvc engine handles automatically are handled this way...that is the Mvc Engine look at the attributes of the MetaDataType and merge them with the native attributes...You have to do the same in your custom code.

That said if you need your attribute in a view...instead of retrieving manually your attributes, write a custom MetaDataProvider. The metadata provider logics automatically retrieve for you all attributes(the way I explained)...you need just to specify what action to take for each of them.

2
Darin Dimitrov On

Make sure that the namespace into which is defined your autogenerated class is the same as the one in which you defined your custom partial class. For example:

namespace FooBar
{
    [Table(Name = "T_MKT_Product")]
    public partial class T_MKT_Product : GlobalSist.DataAccess.Base.BaseEntity
    {
        ...
    }
}

and yours:

namespace FooBar
{
    [MetadataType(typeof(ProductMetaData))]
    public partial class T_MKT_Product
    {
    }

    public class ProductMetaData
    {
        [Display(Order = -1)]
        public virtual string Code { get; set; }

        [Display(Order = -2)]
        public object Name { get; set; }

        [Display(Order = -3)]
        public object Description { get; set; }
    }
}