【问题标题】:generated WCF client tries to serialize private members in Dynamics 365生成的 WCF 客户端尝试序列化 Dynamics 365 中的私有成员
【发布时间】:2018-02-20 08:09:51
【问题描述】:

我编写了几个调用相同 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 服务。我还有其他调用其他 Web 服务(使用其他生成的服务参考代码)的 CRM 插件也可以正常工作。我还尝试更改插件使用的 URL,因此它应该引发 404,以确保 Web 服务不会引发错误,并且它仍然引发相同的异常,因此它必须是客户端异常。我很茫然。

我唯一能想到的是,拥有多个具有相同公共类型的插件程序集可能会导致这种情况,但恕我直言,这太随机了。

有人知道这里发生了什么吗?

【问题讨论】:

    标签: c# dynamics-crm service-reference dynamics-365


    【解决方案1】:

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

    我建议您查看Partial Trust Best PracticesPartial Trust Feature Compatibility WCF 文档。快速浏览一下服务参考代码可以看出,该类被标记为[System.SerializableAttribute()],这在部分信任环境中不受支持,并且[DataContract] 没有被用来显式地将该类声明为可序列化。从表面上看,您必须更新合约以使其与部分信任兼容。

    【讨论】:

      【解决方案2】:

      原来有一些逻辑决定是使用XmlSerializer 还是DataContractSerializer,见这里:

      Add Service Reference is ALWAYS generating xmlserializer and not DataContractSerializer

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-22
        • 1970-01-01
        • 1970-01-01
        • 2012-06-17
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多