0

I am using a database first approach and have a class SalesWallboard mapped to the database table.

SalesWallboard.cs:

namespace Wallboards.DAL.SchnellDb
{
    public partial class SalesWallboard
    {
        public int Id { get; set; }
        public string StaffName { get; set; }
        ...
    }
}

I have created a MetadataType class for this to apply custom attributes

SalesWallboardModel.cs

namespace Wallboards.DAL.SchnellDb
{
    [MetadataType (typeof(SalesWallboardModel))]
    public partial class SalesWallboard
    {

    }

    public class SalesWallboardModel
    {
        [UpdateFromEclipse]
        public string StaffName { get; set; }
        ...
    }
}

But in my code, when I check it using Attribute.IsDefined, it always throws false.

Code

var salesWallboardColumns = typeof(SalesWallboard).GetProperties();
foreach (var column in salesWallboardColumns)
{
    if (Attribute.IsDefined(column, typeof(UpdateFromEclipse))) //returns false
    {
        ...
    }
}

I have checked the answer given here. But I don't understand the example. Can someone please simplify this for me?

prinkpan
  • 2,117
  • 1
  • 19
  • 32
  • 3
    You are checking the properties of the wrong type. Your custom attribute is defined on a property of the `SalesWallboardModel` type, not `SalesWallboard`. – thehennyy Feb 17 '19 at 13:57
  • If i understand your intention correctly (i might be totally wrong), you would need to check the presence of the MetadataType attribute on the SalesWallboard class. If the attribute is present, get the metadata-class-type object from it. Then check the properties of this metadata-class-type for the presence of the UpdateFromEclipse attribute (this is exactly what the accepted answer in the question you linked does. Pay close attention to the code in the accepted answer.) –  Feb 17 '19 at 14:03
  • @thehennyy, if I am not wrong since SalesWallboardModel is a MetadataType class for SalesWallboard, shouldn't I be able to use SalesWallboard instead? Because, if I change `var salesWallboardColumns = typeof(SalesWallboard).GetProperties();` to `var salesWallboardColumns = typeof(SalesWallboardModel).GetProperties();` my code breaks in lines ahead where I am setting value for property in SalesWallboard. – prinkpan Feb 17 '19 at 14:07
  • 2
    @PriyankPanchal, you are reflecting on properties of SalesWallboard (which do not have UpdateFromEclipse attributes applied), not SalesWallboardModel. The presence of a MetadataType attribute does not change that fact at all. The presence of attributes does not magically make code/reflection behave differently.. –  Feb 17 '19 at 14:08
  • @elgonzo your second part of query is right, I need to check presence of UpdateFromEclipse attribute. I don't want to check the presence of MetadataType attribute on class. – prinkpan Feb 17 '19 at 14:09
  • If you don't want to check the presence of the MetadataType attribute, then your only way is to explicitly check SalesWallboardModel properties like `typeof(SalesWallboardModel).GetProperties();` (but i doubt it makes much sense to hard-code `typeof(SalesWallboardModel)`; because what if the class in the MetadataType attribute is being changed?) –  Feb 17 '19 at 14:10
  • @elgonzo, so you mean I need to loop through all classes having MetadataType attribute on it then for the one matching SalesWallboard, I loop through properties and check the presence of UpdateFromEclipse attribute? Can you please give an example of doing this by checking the presence of MetadataType? I can check if it works for me. Thank you. – prinkpan Feb 17 '19 at 14:19
  • 1
    I don't know what you want and need to do. Your question here is about SalesWallboard class and an associated SalesWallboardModel class. What you are trying to ask now is not about your question anymore, and is on the verge of turning into a long-winded discussion. Perhaps it would be a good idea to take some time to think it through, then, if you are still struggling with some aspects of your application, ask another, new question that clearly and unambiguously explains the actual problem you are having... –  Feb 17 '19 at 14:24
  • Thank you @elgonzo, I have found the answer. Please check below. – prinkpan Feb 17 '19 at 17:14

1 Answers1

0

I would like to thank @elgonzo and @thehennyy for their comments and correcting my understanding with reflection.

I found what I was looking for here. But I had to make a few modifications shown below.

I created a method PropertyHasAttribute

private static bool PropertyHasAttribute<T>(string propertyName, Type attributeType)
{
    MetadataTypeAttribute att = (MetadataTypeAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(MetadataTypeAttribute));
    if (att != null)
    {
        foreach (var prop in GetType(att.MetadataClassType.UnderlyingSystemType.FullName).GetProperties())
        {
            if (propertyName.ToLower() == prop.Name.ToLower() && Attribute.IsDefined(prop, attributeType))
                return true;
        }
    }
    return false;
}

I also got help from here because my type was in a different assembly.

Method GetType

public static Type GetType(string typeName)
{
    var type = Type.GetType(typeName);
    if (type != null) return type;
    foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
    {
        type = a.GetType(typeName);
        if (type != null)
            return type;
    }
    return null;
}

Then used it in my code like so

Code

var salesWallboardColumns = typeof(SalesWallboard).GetProperties();
foreach (var column in salesWallboardColumns)
{
    var columnName = column.Name;
    if (PropertyHasAttribute<SalesWallboard>(columnName, typeof(UpdateFromEclipse)))
    {
        ...
    }
}
prinkpan
  • 2,117
  • 1
  • 19
  • 32