?
Solved

C# - Reflection - How to get attribute "DataContract" for child objects

Posted on 2012-08-30
6
Medium Priority
?
1,277 Views
Last Modified: 2012-09-21
I have a class as followed:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;

/// <summary>
/// Summary description for Class1
/// </summary>
public static class Class1
{
	

    public class ParentObject
    {
        public int pp1 { get; set; }
        public int pp2 { get; set; }
        public ChildObject child1 { get; set; }
    }

    [DataContract]
    public class ChildObject
    {
        public int cp1 { get; set; }
        public int cp2 { get; set; }
    }
}

Open in new window


I want to use reflection to go through all properties of ParentObject and determine which property has attribute "DataContract" (in this case, the answer is property of type ChildObject. But I need the code to determine this answer dynamically).

For instance, I know I can get list of properties in ParentObject by using the following code:
Type parent = typeof(Class1.ParentObject);
        System.Reflection.PropertyInfo[] properties = parent.GetProperties();

Open in new window


But how do I find out which property has attribute "DataContract"?
0
Comment
Question by:fippif
  • 3
  • 2
6 Comments
 
LVL 29

Expert Comment

by:QPR
ID: 38353180
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 38353231
This can be achieved in one line with Linq extension methods:

            PropertyInfo dataprop = parent.GetProperties().FirstOrDefault(p => p.GetCustomAttributes(typeof(DataContractAttribute), false).Length > 0);

you will need to declare the System.Linq namespace at the top of your file.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:fippif
ID: 38368283
None of these responses resolved my issue. It seems the provided samples look at all the attributes for properties in ParentObject class. For instance, I added "Required" attributed to child1 property in class ParentObject:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;
using System.ComponentModel.DataAnnotations;

/// <summary>
/// Summary description for Class1
/// </summary>
public static class Class1
{
	

    public class ParentObject
    {
        public int pp1 { get; set; }
        public int pp2 { get; set; }

        [Required] // new attribute
        public ChildObject child1 { get; set; }
    }

    [DataContract]
    public class ChildObject
    {
        public int cp1 { get; set; }
        public int cp2 { get; set; }
    }
}

Open in new window


And I modified my code as followed (please note the return results):

 Class1.ParentObject p = new Class1.ParentObject() { pp1 = 1, pp2 = 2, child1 = new Class1.ChildObject() };

        Type pType = p.GetType();

        bool b = pType.GetCustomAttributes(typeof(DataContractAttribute), true).Any(); // returns false
        PropertyInfo dataprop = pType.GetProperties().FirstOrDefault(prop => prop.GetCustomAttributes(typeof(DataContractAttribute), false).Length > 0); // returns null


        var props = pType.GetProperties();

        foreach (PropertyInfo itemProperty in props)
        {
            bool bc = itemProperty.GetCustomAttributes(typeof(DataContractAttribute), true).Any(); // returns false for all properties

            bool bc1 = itemProperty.GetCustomAttributes(typeof(RequiredAttribute), true).Any(); // returns true for property child1
        }

Open in new window


It seems the Required attribute for child1 object is recognized by the sample codes you provided. But the DataContractAttribute is NOT recognized for ChildObject type. Do you see a problem with my code? Am I doing something wrong?
Thx.
0
 

Accepted Solution

by:
fippif earned 0 total points
ID: 38404404
In case this response helps others, it appears I needed PropertyType property of itemProperty. So, for the following class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;
using System.ComponentModel.DataAnnotations;

namespace CustomAttributeTest
{
    public class Class1
    {
    }

    [DataContract]
    public enum Enum1
    {
        [EnumMember]
        item1,

        [EnumMember]
        item2
    }

    [DataContract]
    public class GrandChildClass
    {
        [Required(ErrorMessage = "prop1 of GrandChildClass is required")]
        public int? prop1 { get; set; }

        [Required(ErrorMessage = "prop2 of GrandChildClass is required")]
        public Enum1? prop2 { get; set; }
    }
    
    
    [DataContract]
    public class ChildClass
    {
        [Required(ErrorMessage = "prop1 of ChildClass is required")]
        public int? prop1 { get; set; }

        [Required(ErrorMessage = "prop2 of ChildClass is required")]
        public GrandChildClass prop2 { get; set; }
    }

    [DataContract]
    public class ParentClass
    {
        public int prop1 { get; set; }

        [Required(ErrorMessage = "prop2 of ParentClass is required")]
        public ChildClass prop2 { get; set; }
    }


}

Open in new window


I added the following method:

private static void ProcessTypes(object entity, List<object> lstEntity)
        {
            if (entity == null)
            {
                continueLoop = false;
            }

            while (continueLoop)
            {
                // Add entity to the list
                lstEntity.Add(entity);

                Type pType;
                // Get the type
                pType = entity.GetType();

                // Get all subtypes

                List<PropertyInfo> lstPropertyInfo = pType.GetProperties().Where(r => r.PropertyType.GetCustomAttributes(typeof(DataContractAttribute), true)
                            .Any())
                            .ToList();

                if (lstPropertyInfo.Count > 0)
                {
                    foreach (PropertyInfo itemProperty in lstPropertyInfo)
                    {
                        object newEntity = itemProperty.GetValue(entity, null);
                        ProcessTypes(newEntity, lstEntity);
                    }
                }
                else
                {
                    continueLoop = false;
                }

            }
            
        }

Open in new window


And called this method as followed:

List<object> lstEntity = new List<object>();

            GrandChildClass gcc = new GrandChildClass() { prop1 = 1, prop2 = Enum1.item1 };

            ProcessTypes(gcc, lstEntity);

Open in new window

0
 

Author Closing Comment

by:fippif
ID: 38421065
The comments provided by experts did not refer to the detailed problem I had. Instead, those comments provided links to answers I had found online already. Furthermore, when I added more details to my question, none of the experts responded back. Unfortunately, the experts did not effectively help me with my question.
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question