Warren LaFrance
Warren LaFrance

Reputation: 582

C# Get object inside of object that is a generic

I have several View Models that contain a address object. That address object of course has address1, address2, city, state, and zip.
We are using the postal code address verification system, and I want all of my developers to be able to call a helper class, that will sniff View Model object for a address object. If it does not find it, it will then check to see if the view model has basic address1, address2 and etc properties... In either case I need it to get the address information for either the property object address or get the address properties...

So my helper class method signature looks like this:

 public void ShowVerificationWithReflection<T>(ModelStateDictionary modelState, T viewModel) where T : AMSBaseVM

I then do the following:

var objType = viewModel.GetType();
List<PropertyInfo> properties = new List<PropertyInfo>();

properties.AddRange(objType.GetProperties());

foreach (PropertyInfo property in properties)
{
    if (property.CanRead)
    {
        if (property.Name == "Address1") testAddress.Address1 = property.GetValue(viewModel, null) as string;
        if (property.Name == "Address2") testAddress.Address2 = property.GetValue(viewModel, null) as string;
        if (property.Name == "City") testAddress.City = property.GetValue(viewModel, null) as string;
        if (property.Name == "StCd") testAddress.StateCodeId = (long)property.GetValue(viewModel, null);
        if (property.Name == "Zip") testAddress.Zip = property.GetValue(viewModel, null) as string;
    }
}

This works for the address properties that part of the View Model. Now what I am stumbling with is detecting if the View Model has a property like this:

 public EntityAddressVM Address { get; set; }

I need to get that object from the generic and then get its address properties. I have been able to find the object, but after that I get stuck...

 bool hasEntityAddress = objType.GetProperties().Any(p => p.PropertyType == typeof(EntityAddressVM));

What I am needing help with is:

  1. Determine if incoming viewModel (mvc) has a address object or has address properties.

  2. If it does have address Object, get the address properties otherwise get the address properties from the ViewModel.

Upvotes: 3

Views: 5038

Answers (1)

Dmitri Trofimov
Dmitri Trofimov

Reputation: 763

There is one nice extension method that I use to look at objects properties:

/// <summary>
///     Gets all public properties of an object and and puts them into dictionary.
/// </summary>
public static IDictionary<string, object> ToDictionary(this object instance)
{
    if (instance == null)
        throw new NullReferenceException();

    // if an object is dynamic it will convert to IDictionary<string, object>
    var result = instance as IDictionary<string, object>;
    if (result != null)
        return result;

    return instance.GetType()
        .GetProperties()
        .ToDictionary(x => x.Name, x => x.GetValue(instance));
}

Then you can do something like this:

var addressObject = model
    .ToDictionary()
    .FirstOrDefault(x => x.Value is EntityAddressVM)
    .Value;

If its null then get Address properties from model.

Hope this helps.

Upvotes: 2

Related Questions