Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetValue of PropertieInfo throws TargetParameterCountException (System.Reflection)

I mistakenly posted this question already at the SharePoint part.

I need to map one model onto an other. Everything works well but the last property throws a TargetParameterCountException. The property which throws the exception is called "Item" this property is not defined by me, I assume that this is a property from the dictionary.

I already tried to use all five parameters instead of only one (as described here Moq + Unit Testing - System.Reflection.TargetParameterCountException: Parameter count mismatch) but unfortunately i will get the same exception. I would really appreciate it if someone could help me.

Kinde Regards and Thanks

Sandro

That is a excerpt of the Source Model, all other properties are implemented in exactly the same way:

public class DataModel : Dictionary<string, object> {}
public class DiscussionDataModel : DataModel
{
  public DiscussionDataModel(Dictionary dictionary) : base(dictionary){}

  public FieldUserValue Author
  {
    get { return (FieldUserValue) this["Author"]; }
    set { this["Author"] = value; }
  }

  public double AverageRating
  {
    get { return (double) this["AverageRating"]; }
    set { this["AverageRating"] = value; }
  }
}

And that is a excerpt the target Model, all other properties are implemented in exactly the same way:

public class DiscussionModel : BaseModel
{
  public FieldUserValue Author { get; set; }
  public double AverageRating { get; set; }
}

And this is the generic extension method to map the DataModel onto the BaseModel:

public static T ToModel(this DataModel dataModel) where T : BaseModel
{
  try
  {
    T model = Activator.CreateInstance();
    if (dataModel != null)
    {
      PropertyInfo[] propertyInfos = dataModel.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

      foreach (PropertyInfo propertyInfo in propertyInfos)
      {
        object value = propertyInfo.GetValue(dataModel);
        if (value == null) { break; }
        PropertyInfo modelPropertyInfo = model.GetType().GetProperty(propertyInfo.Name);
        modelPropertyInfo?.SetValue(model, value);
      }
      return model;
    }
  }
  catch (Exception ex)
  {
    throw;
  }
  return null;
}
like image 395
Sandro Paetzold Avatar asked Apr 26 '16 06:04

Sandro Paetzold


1 Answers

The problem is that the Item property is indexed, i.e. it has a parameter. C# normally does not allow this, but other .NET languages such as VB.NET do. Thus, this concept is known to the CLR and thus also to Reflection. In C#, there is only one way to create an indexed property, namely through an indexer. What this does at a CLR-level is to create an indexed propery called Item, so you might have just stumbled across an indexer.

So the solution is to check the property info whether it has parameters and continue the for loop if this is the case. There is no chance for you to know generically what objects to pass into an indexed property.

like image 64
Georg Avatar answered Nov 02 '22 05:11

Georg