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

 手机用户2502939177 发布于 2023-02-09 10:39

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

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


    ...

但我的Web服务期望在错误的命名空间中使用不同的东西,并使用修改后的元素名称.这就是我的WSDL中定义DocuSignConnectUpdate方法的方法:


    
        
            
        
    

这就是我在WSDL中定义DocuSignEnvelopeInformation类型的方式:


    
        
        
        
        
        
        
    

像envelopeStatusField这样的元素名称是自动生成的代码中使用的私有变量的名称.公共属性名称与DocuSign发送的xml相匹配.自动生成的代码还使用XmlTypeAttribute使用正确的docusign命名空间标记每个对象.因此,通过查看自动生成的代码,我希望我的服务对输入感到满意,但生成的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;

    /// 
    [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会以这种方式出现?为什么对象与我从中提取的引用不同?更重要的是,我可以解决它吗?

1 个回答
  • 令我惊讶的是,我花了多少时间在这上面,我尝试了多少解决方案,我遵循了多少链接,以及我读过多少SO答案,但在最终找到答案之前没有回答我的问题坐在这里超过2年!

    根本问题是默认情况下DataContractSerializer正在序列化和反序列化DocuSignEnvelopeInformation对象.这基本上序列化了构成对象的私有成员变量,而不是公共属性.令人高兴的是,这是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);
    }
    

    就像那样,公共属性及其声明的命名空间和我需要的一切现在都被序列化而不是私有数据!

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

    2023-02-09 10:43 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有