Reputation: 5106
I've got an object that has a collection of properties. When I get the specific entity I can see the field I'm looking for (opportunityid
) and that it's Value
attribute is the Guid
for this opportunity. This is the value I want, but it won't always be for an opportunity, and therefore I can't always look at opportunityid
, so I need to get the field based on input supplied by the user.
My code so far is:
Guid attrGuid = new Guid();
BusinessEntityCollection members = CrmWebService.RetrieveMultiple(query);
if (members.BusinessEntities.Length > 0)
{
try
{
dynamic attr = members.BusinessEntities[0];
//Get collection of opportunity properties
System.Reflection.PropertyInfo[] Props = attr.GetType().GetProperties();
System.Reflection.PropertyInfo info = Props.FirstOrDefault(x => x.Name == GuidAttributeName);
attrGuid = info.PropertyType.GUID; //doesn't work.
}
catch (Exception ex)
{
throw new Exception("An error occurred when retrieving the value for " + attributeName + ". Error: " + ex.Message);
}
}
The dynamic attr
contains the field I'm looking for (in this case opportunityid
), which in turn contains a value field, which is the correct Guid
. However, when I get the PropertyInfo
info (opportunityid
) it no longer has a Value
attribute. I tried looking at the PropertyType.GUID
but this doesn't return the correct Guid
. How can I get the value for this property?
Upvotes: 43
Views: 88223
Reputation: 13
Some people are facing same kind of issue like fetching key and value both. In that below example provide to you whole information with code like how can achieve both things.
//Contact represent to as class
Contact contact = new Contact();
Type exType = contact!.GetType();
List<PropertyInfo> props = new List<PropertyInfo>(exType.GetProperties());
foreach (var item in props)
{
Console.Writeline("Key"+ item.Name);
Console.Writeline("Value"+ item.GetValue(contact)!.ToString());
}
Upvotes: 0
Reputation: 697
Jut to add that this can be achieved via reflection (even for properties in un-instantiated, nested classes / types)
Imports System
Imports System.Reflection
Public Class Program
Public Shared Sub Main()
Dim p = New Person()
For Each nestedtype in p.Gettype().GetNestedTypes()
For Each prop in nestedtype.GetProperties(BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Static)
Console.WriteLine(nestedtype.Name & " => " & prop.Name)
Next
Next
End Sub
End Class
Public Class Person
Public Property Name As String
Public Property AddressDetail As Address
Public Class Address
Public Property Street As String
Public Property CountryDetail As Country
End Class
Public Class Country
Public Property CountryName As String
End Class
End Class
Prints the following:
Address => Street
Address => CountryDetail
Country => CountryName
fiddle: https://dotnetfiddle.net/6OsRkp
Upvotes: 0
Reputation: 7773
Use PropertyInfo.GetValue()
. Assuming your property has the type Guid?
then this should work:
attrGuid = ((System.Guid?)info.GetValue(attr, null)).Value;
Note that an exception will be thrown if the property value is null.
Upvotes: 3
Reputation: 726489
Unless the property is static
, it is not enough to get a PropertyInfo
object to get a value of a property. When you write "plain" C# and you need to get a value of some property, say, MyProperty
, you write this:
var val = obj.MyProperty;
You supply two things - the property name (i.e. what to get) and the object (i.e. from where to get it).
PropertyInfo
represents the "what". You need to specify "from where" separately. When you call
var val = info.GetValue(obj);
you pass the "from where" to the PropertyInfo
, letting it extract the value of the property from the object for you.
Note: prior to .NET 4.5 you need to pass null as a second argument:
var val = info.GetValue(obj, null);
Upvotes: 68
Reputation: 156948
If the name of the property is changing, you should use GetValue
:
info.GetValue(attr, null);
The last attribute of that method can be null
, since it is the index value, and that is only needed when accessing arrays, like Value[1,2]
.
If you know the name of the attribute on beforehand, you could use the dynamic
behavior of it: you can call the property without the need of doing reflection yourself:
var x = attr.Guid;
Upvotes: 6