gpt4 book ai didi

wcf - 为什么我的 WCF Web 服务在具有不同字段名称的不同命名空间中显示此对象?

转载 作者:行者123 更新时间:2023-12-03 18:25:12 28 4
gpt4 key购买 nike

上下文:我正在尝试与 DocuSign 的 Connect 通知服务集成。我已经使用称为 DocuSignConnectUpdate 的方法设置了 WCF 服务,该方法将 DocuSignEnvelopeInformation 作为其唯一参数,由 DocuSign 指定。此 DocuSignEnvelopeInformation 对象来自对 their API 的引用,以便他们可以将此对象传递给我的 Web 服务,而我确切地知道会发生什么。 DocuSign 询问我的服务地址和命名空间,这是我在他们的网站上配置的。

问题: DocuSign 发送的 XML 是我所期望的。 DocuSignEnvelopeInformation 及其子项位于命名空间“http://www.docusign.net/API/3.0”中,元素名称与对象名称匹配:

<DocuSignEnvelopeInformation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.docusign.net/API/3.0">
<EnvelopeStatus>...</EnvelopeStatus>
</DocuSignEnvelopeInformation>

但是我的 Web 服务期望在错误的命名空间中出现不同的东西,并且修改了元素名称。这就是在我的 WSDL 中定义 DocuSignConnectUpdate 方法的方式:
<xs:element name="DocuSignConnectUpdate">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="DocuSignEnvelopeInformation" nillable="true" type="tns:DocuSignEnvelopeInformation"/>
</xs:sequence>
</xs:complexType>
</xs:element>

这就是在我的 WSDL 中定义 DocuSignEnvelopeInformation 类型的方式:
<xs:complexType name="DocuSignEnvelopeInformation">
<xs:sequence>
<xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/System.ComponentModel" name="PropertyChanged" nillable="true" type="q1:PropertyChangedEventHandler"/>
<xs:element name="documentPDFsField" nillable="true" type="tns:ArrayOfDocumentPDF"/>
<xs:element name="envelopeStatusField" nillable="true" type="tns:EnvelopeStatus"/>
<xs:element name="timeZoneField" nillable="true" type="xs:string"/>
<xs:element name="timeZoneOffsetField" type="xs:int"/>
<xs:element name="timeZoneOffsetFieldSpecified" type="xs:boolean"/>
</xs:sequence>
</xs:complexType>

像信封状态字段这样的元素名称是自动生成代码中使用的私有(private)变量的名称。公共(public)属性名称与 DocuSign 发送的 xml 匹配。自动生成的代码还使用 XmlTypeAttribute 使用正确的文档名命名空间标记每个对象。因此,通过查看自动生成的代码,我希望我的服务对输入感到满意,但是生成的 WSDL 不同,如上所示,并且我的服务无法反序列化 xml。

部分代码:
DocuSignEnvelopeInformation 的自动生成声明:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.17929")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.docusign.net/API/3.0")]
public partial class DocuSignEnvelopeInformation : object, System.ComponentModel.INotifyPropertyChanged {

private EnvelopeStatus envelopeStatusField;

private DocumentPDF[] documentPDFsField;

private string timeZoneField;

private int timeZoneOffsetField;

private bool timeZoneOffsetFieldSpecified;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public EnvelopeStatus EnvelopeStatus {
...
...

唯一方法的 OperationContract:
[SoapHeaders]
[ServiceContract(Namespace = "http:/MyNameSpace")]
public interface IDocusignEventListener
{
[OperationContract]
[FaultContract(typeof(ErrorMessageCollection), Action = Constants.FaultAction)]
string DocuSignConnectUpdate(DocuSignEnvelopeInformation DocuSignEnvelopeInformation);
}

DocuSign 调用的方法
[ServiceBehavior(Namespace = "http:/MyNameSpace", ConfigurationName = "DocusignEventListener")]
public class DocusignEventListener : IDocusignEventListener
{
public string DocuSignConnectUpdate(DocuSignEnvelopeInformation DocuSignEnvelopeInformation)
{
...

return DocuSignEnvelopeInformation.EnvelopeStatus.EnvelopeID;
}
}

所以,再一次,问题是为什么 wsdl 会以这种方式出现?为什么该对象与我从中提取它的引用不同?更重要的是,我可以修复它吗?

最佳答案

令人震惊的是,我花了多少小时,尝试了多少解决方案,关注了多少链接,以及在最终找到答案之前,我读过多少 SO 答案并没有回答我的问题坐着right here在 SO 上超过 2 年!

根本问题是 DocuSignEnvelopeInformation 对象默认被 DataContractSerializer 序列化和反序列化。这实质上序列化了在其本地命名空间中构成对象的私有(private)成员变量,而不是公共(public)属性。令人生气的是,这是 WCF 服务的默认序列化程序。如果服务应用程序的自动生成代码至少将示例方法标记为 [DataContractFormat]明确地说,我们会有一个线索可以遵循,但这只是一个你必须以某种方式预测的无形默认值。

解决方案是用 [XmlSerializerFormat] 标记每个方法在界面中。这将 DataContractSerializer 替换为 XmlSerializer 作为方法参数的序列化器:

[SoapHeaders]
[ServiceContract(Namespace = "http://www.docusign.net/API/3.0")]
public interface IDocusignEventListener
{
[OperationContract]
[XmlSerializerFormat]
[FaultContract(typeof(ErrorMessageCollection), Action = Constants.FaultAction)]
string DocuSignConnectUpdate(DocuSignEnvelopeInformation DocuSignEnvelopeInformation);
}

就像这样,带有声明的命名空间和我需要的一切的公共(public)属性现在被序列化而不是私有(private)数据!

对于我的具体问题,要接收来自 DocuSign 的 Connect 通知服务的电话,我仍然有一个小的命名空间问题。根级参数 DocuSignEnvelopeInformation 仍在方法调用的命名空间中。我不确定为什么。现在,我只是将方法调用本身放在 DocuSign API 命名空间中(如您在上面的代码示例中所见)。该服务现在可以正确反序列化这些调用。

关于wcf - 为什么我的 WCF Web 服务在具有不同字段名称的不同命名空间中显示此对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20686436/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com