Search code examples
c#reflectiondynamics-crm-2011

C# Reflection exception Method not found


Hi I'm developing CRM 2011 Plugin and I have a problem with reflected type. I have generated Entities classes and I know that property exists in the type but when I try to get its value I'm getting exception about method not being found. The stupidest part is that it works perfectly on my machine but doesn't work on clients.

Here's my code (I need to take all OptionSets from the entity and perform action on them):

public override void MyExecute()
        {
            var fse = TargetEntity.ToEntity<Equipment>();
            Type equiptmentType = fse.GetType();
            TracingService.Trace("FSE object type: {0}", equiptmentType.FullName);
            IEnumerable<PropertyInfo> optionSetsProperties = equiptmentType.GetProperties()
                .Where(x => x.PropertyType == typeof(OptionSetValue)).ToList();  //I'm getting this property from the object type so it must exist.


            foreach (var optionSetsProperty in optionSetsProperties)
            {   
                TracingService.Trace("Resolving ResourceGroup on property: {0}", optionSetsProperty.Name);
                ResolveResourceGroupBySkill(optionSetsProperty, fse);
                TracingService.Trace("Resoloving ResourceGroup finished");
            }

        }

private void ResolveResourceGroupBySkill(PropertyInfo optionSetsProperty, Equipment fse)
        {
            try
            {
                TracingService.Trace("Trying to get value of: {0}", optionSetsProperty.Name);

                OptionSetValue skillLevel = (OptionSetValue)optionSetsProperty.GetValue(fse);
                TracingService.Trace("Value equals: {0}", skillLevel);

            }
            catch (Exception ex)
            {
                TracingService.Trace("An error occured: {0}", ex.Message);
                Exception inner = ex;
                while (inner != null)
                {
                    TracingService.Trace(inner.Message);
                    inner = inner.InnerException;
                }
                throw new InvalidOperationException(String.Format("Cannot get value of skill level from property: {0}", optionSetsProperty.Name), ex);
            }
        }

Here's the Log details:

Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Method not found: 'System.Object System.Reflection.PropertyInfo.GetValue(System.Object)'.Detail: 
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
  <ErrorCode>-2147220891</ErrorCode>
  <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
    <KeyValuePairOfstringanyType>
      <d2p1:key>OperationStatus</d2p1:key>
      <d2p1:value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:string">0</d2p1:value>
    </KeyValuePairOfstringanyType>
  </ErrorDetails>
  <Message>Method not found: 'System.Object System.Reflection.PropertyInfo.GetValue(System.Object)'.</Message>
  <Timestamp>2014-09-11T12:58:09.2941554Z</Timestamp>
  <InnerFault i:nil="true" />
  <TraceText>

[OC.CSSFieldService: OC.CSSFieldService.ServiceActivity.MyPlugin]
[424ad2a7-ea29-e411-be7f-00155d0aa109: OC.CSSFieldService.ServiceActivity.MyPlugin: Create of equipment]
FSE object type: OC.Data.Equipment
Resolving ResourceGroup on property: oc_ExpeCommHyper

</TraceText>
</OrganizationServiceFault>

As you can see even the tracing line "Trying to get value of" is not working. The exception is not caught... I don't know what to do. Any thoughts?


Solution

  • Ok I figured it out. The server has Microsft .NET 4.0 installed and I have .NET 4.5.

    In the .NET 4.5 there's a new overload for PropertyInfo.GetValue method - it's PropertyInfo.GetValue(object obj) since in 4.0 there is only PropertyInfo.GetValue(object obj, object[] indexer)

    I just had to replace:

     OptionSetValue skillLevel = (OptionSetValue)optionSetsProperty.GetValue(fse);
    

    with

    OptionSetValue skillLevel = (OptionSetValue)optionSetsProperty.GetValue(fse, null);
    

    worked like a charm!