如何自定义 SOAP Web 服务命名空间

Posted

技术标签:

【中文标题】如何自定义 SOAP Web 服务命名空间【英文标题】:How are SOAP web service namespaces customized 【发布时间】:2022-01-17 08:05:46 【问题描述】:

我正在使用soapcore 在asp.net core 中编写一个soap web 服务来替换现有的web 服务。调用者的请求 xml 不能更改,因为我们打算尽量减少那一侧的更改。 当前请求 xml 看起来像

<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ser="http://vendornamespace.com/"
    xmlns:idat="http://schemas.datacontract.org/2004/07/iDataContract">
    <soapenv:Header/>
    <soapenv:Body>
        <ser:ActionRequest>
            <ser:composite>
                <idat:param1>H04</idat:param1>
                <idat:param2>100</idat:param2>
            </ser:composite>
        </ser:PlaceOrder>
    </soapenv:Body>
</soapenv:Envelope>

我的网络服务界面看起来像

public interface INewWebsServices

    [OperationContract(Action = "ActionRequest")]
    Task<WebSvcResponseClass> ActionRequest([MessageParameter(Name = "composite")] WebServiceReqactionMethod_A);

我的请求类看起来像

[DataContract (Namespace = "http://schemas.datacontract.org/2004/07/iDataContract", Name ="idat")]
    
[MessageContract()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.datacontract.org/2004/07/iDataContract")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.datacontract.org/2004/07/iDataContract", IsNullable = false)]
public class WebServiceReq

    [MessageBodyMember]
    public string param1  get; set; 

    [MessageBodyMember]
    public string param2  get; set; 

这会生成一个网络服务请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ser="http://vendornamespace.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:PlaceOrder>
         <ser:composite>            
            <ser:param1>?</ser:param1>            
            <ser:param2>?</ser:param2>
         </ser:composite>
      </ser:PlaceOrder>
   </soapenv:Body>
</soapenv:Envelope>

很明显,标头中缺少 idat 命名空间,并且未在 Web 请求参数中使用。

如何修改我的 WebServiceReq 类以包含缺少的命名空间,以便 SoapCore 可以正确地反序列化传入的请求。

【问题讨论】:

您可以阅读this article 找到解决方案。 【参考方案1】:

您可以尝试在命名空间 iDataContract 中定义 WebSvcResponseClass,也可以使用 [DataMember] 而不是 [MessageBodyMember] 来装饰属性。 此外,您可以将服务接口定义为

public interface INewWebsServices


    [System.ServiceModel.OperationContractAttribute(Action = "http://domain/namespace", ]
        Task<iDataContract.WebSvcResponseClass> WebServiceReqactionMethod_A(iDataContract.WebserviceRequestclass composite); 

如果您尝试使用soapUI,则使用命名空间会在Web 服务请求中生成idat 作为前缀。

【讨论】:

以上是关于如何自定义 SOAP Web 服务命名空间的主要内容,如果未能解决你的问题,请参考以下文章

使用命名空间的 SOAP 消息

如何删除Zend_Soap中的命名空间?

如何使用 Apache Axis2 和 WSDL2Java 向 SOAP 响应添加命名空间引用

来自 Siebel 的 SOAP 请求在每个元素中都有命名空间

如何更改Spring-WS的“SOAP-ENV”默认前缀

如果命名空间声明在 SOAP 信封上,如何使用 JAXB 解组 SOAP 响应?