1

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?

Daniel Schmid
  • 362
  • 1
  • 5
  • 20

2 Answers2

1

The main thing to understand here is that Dynamics 365 Online will execute your code in partial trust (also called Sandbox in D365) which will add some restrictions on what you can do inside your plugin. For this reason, your test using a console application (full trust) is not representative and it will work fine as you mentioned.

I recommend you to give a look to the Partial Trust Best Practices and Partial Trust Feature Compatibility WCF documentation. A quick look of the service reference code shows that the class is marked as [System.SerializableAttribute()] which is not supported in partial trust environments and the [DataContract] is not being used to explicitly declare the class as serializable. By the look of it, you will have to update the contract to make it partial-trust compatible.

Federico Jousset
  • 1,661
  • 14
  • 21
0

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.

Daniel Schmid
  • 362
  • 1
  • 5
  • 20