Search code examples
c#dynamics-crmservice-referencedynamics-365

generated WCF client tries to serialize private members in Dynamics 365


I wrote several CRM plugins which call the same web service. All those plugins share the same generated service reference code. The code was stored inside a library which was then merged with the plugin DLLs. This worked in the old on premise CRM.

We're now migrating the relevant on premise CRM system to Dynamics 365 which introduces a problem: calling the service using the generated *Client class raises this exception:

System.Security.SecurityException: The data contract type 'MyNamespace.MyDataContract' cannot be serialized in partial trust because the member 'MyDataMemberField' is not public. ---> System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

The important part of the exception is the MyDataMemberField.

The generated code looks like this:

[System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "urn:sap-com:document:sap:rfc:functions")]
public class MyDataContract
{
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)]
    public string MyDataMember
    {
        get { return MyDataMemberField; }
        set { MyDataMemberField = value; }
    }

    private string MyDataMemberField;
}

(Note that I left the namespace inside the XmlTypeAttribute unchanged in case this makes a difference I don't know about.)

You can see that judging by the exception there's an attempt to serialize the private member field, and I have no idea why that is. I used the same generated code in a console application, which was able to call the web service just fine. I also have other CRM plugins which call other web services (using other generated service reference code) which also work just fine. I also tried changing the URL used by the plugin so it should raise a 404 just to ensure that the error isn't raised by the web service, and it still raises the same exception, so it must be a client side exception. I'm at a loss.

The only thing I could think of is that having multiple plugin assemblies with the same public types could cause this, but that would be too random imho.

Does anyone have any idea what's going on here?


Solution

  • Turns out there is some logic which determines whether to use XmlSerializer or DataContractSerializer, see here:

    Add Service Reference is ALWAYS generating xmlserializer and not DataContractSerializer

    My situation was that I was provided a WSDL file by our contractor which contained the data types I needed to send from CRM to the WCF. I used svcutil to generate the C# code. This generated code did not have any DataContract or DataMember attributes. Using these types in the WCF resulted in those *Field members to be shown in the types in the WSDL. It also resulted in the CRM plugin to try to use those *Field members for serialization, while those members were private, which then again resulted in the mentioned error.

    Adding the DataContract and DataMember attributes in the generated code fixed both of these issues.