我写了几个调用同一个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服务不会引发错误,并且它仍然引发相同的异常,因此它必须是客户端异常。我不知所措。
我唯一能想到的是拥有多个具有相同公共类型的插件程序集可能会导致这种情况,但这种情况太随机了。
有没有人知道这里发生了什么?
答案 0 :(得分:1)
这里要理解的主要事情是Dynamics 365 Online将以部分信任(在D365中也称为Sandbox)执行您的代码,这将对您在插件中可以执行的操作添加一些限制。出于这个原因,使用控制台应用程序(完全信任)的测试不具有代表性,并且如您所述,它将正常工作。
我建议您查看Partial Trust Best Practices和Partial Trust Feature Compatibility WCF文档。快速查看服务引用代码显示该类标记为[System.SerializableAttribute()]
,在部分信任环境中不支持该类,并且[DataContract]
未用于将类显式声明为可序列化。从表面上看,您必须更新合同才能使其部分信任兼容。
答案 1 :(得分:0)
原来有一些逻辑决定了是否使用XmlSerializer
或DataContractSerializer
,请看这里:
Add Service Reference is ALWAYS generating xmlserializer and not DataContractSerializer
我的情况是我的承包商提供了一个WSDL文件,其中包含我需要从CRM发送到WCF的数据类型。我使用svcutil生成C#代码。此生成的代码没有任何DataContract
或DataMember
属性。在WCF中使用这些类型导致那些*Field
成员显示在WSDL中的类型中。它还导致CRM插件尝试使用这些*Field
成员进行序列化,而这些成员是私有的,这又导致了上述错误。
在生成的代码中添加DataContract
和DataMember
属性修复了这两个问题。