生成的WCF客户端尝试序列化Dynamics 365中的私有成员

问题描述 投票:1回答:2

我写了几个调用相同Web服务的CRM插件。所有这些插件共享相同的生成的服务引用代码。代码存储在一个库中,然后该库与插件DLL合并。这适用于旧的内部部署CRM。

我们现在正在将相关的内部部署CRM系统迁移到Dynamics 365,这会引入一个问题:使用生成的* Client类调用服务会引发此异常:

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.

这个例外的重要部分是MyDataMemberField

生成的代码如下所示:

[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;
}

(请注意,我将XmlTypeAttribute中的命名空间保留不变,以防这会产生影响我不知道。)

您可以看到,通过异常判断尝试序列化私有成员字段,我不知道为什么会这样。我在控制台应用程序中使用了相同的生成代码,它能够很好地调用Web服务。我还有其他CRM插件调用其他Web服务(使用其他生成的服务参考代码)也可以正常工作。我还尝试更改插件使用的URL,因此它应该引发404以确保Web服务不会引发错误,并且它仍然引发相同的异常,因此它必须是客户端异常。我不知所措。

我唯一能想到的是拥有多个具有相同公共类型的插件程序集可能会导致这种情况,但这将是非常随意的imho。

有谁知道这里发生了什么?

c# dynamics-crm service-reference dynamics-365
2个回答
1
投票

这里要理解的主要是Dynamics 365 Online将以部分信任(在D365中也称为Sandbox)执行您的代码,这将对您在插件中可以执行的操作添加一些限制。出于这个原因,使用控制台应用程序(完全信任)的测试不具有代表性,并且如您所述,它将正常工作。

我建议你看看Partial Trust Best PracticesPartial Trust Feature Compatibility WCF文档。快速查看服务引用代码显示该类被标记为[System.SerializableAttribute()],在部分信任环境中不支持,并且[DataContract]未用于将类显式声明为可序列化。从它的角度来看,您将不得不更新合同以使其部分信任兼容。


0
投票

原来有一些逻辑决定是否使用XmlSerializerDataContractSerializer,请看这里:

Add Service Reference is ALWAYS generating xmlserializer and not DataContractSerializer

我的情况是我的承包商提供了一个WSDL文件,其中包含我需要从CRM发送到WCF的数据类型。我使用svcutil生成C#代码。这个生成的代码没有任何DataContractDataMember属性。在WCF中使用这些类型导致那些*Field成员显示在WSDL中的类型中。它还导致CRM插件尝试使用那些*Field成员进行序列化,而这些成员是私有的,然后再次导致提到的错误。

在生成的代码中添加DataContractDataMember属性修复了这两个问题。

© www.soinside.com 2019 - 2024. All rights reserved.