【问题标题】:.NET web service. (ASMX) How can I shape the request and response messages?.NET 网络服务。 (ASMX) 如何塑造请求和响应消息?
【发布时间】:2009-12-18 21:27:33
【问题描述】:

我正在构建一个网络服务来接受来自公司的通知。该公司通知我该服务的结构不正确,并为我提供了一个工作 Web 服务的 .asmx。它看起来像这样:

请求:

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"
       xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <AuthenticationInfo
           xmlns="http://www.usps.com/postalone/services/UserAuthenticationSchema">
      <UserId xmlns="">string</UserId>
      <UserPassword xmlns="">string</UserPassword>
    </AuthenticationInfo>
    <fullServiceAddressCorrectionNotification
            xmlns="http://www.usps.com/postalone/services/POCustomerMailXMLServices">string</fullServiceAddressCorrectionNotification>
  </soap12:Body>
</soap12:Envelope>

回复:

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"
       xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <FullServiceNixieDetailNotificationResponse
         xmlns="http://idealliance.org/maildat/Specs/md091/mailxml70C/mailxml">
      <FullServiceNixieDetailNotificationResult>string</FullServiceNixieDetailNotificationResult>
    </FullServiceNixieDetailNotificationResponse>
  </soap12:Body>
</soap12:Envelope>

我的看起来像这样: 要求:

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"
       xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <FullServiceNixieDetailNotification
          xmlns="http://idealliance.org/maildat/Specs/md091/mailxml70C/mailxml">
      <AuthenticationInfo>
        <UserID>string</UserID>
        <Password>string</Password>
      </AuthenticationInfo>
      <fullServiceAddressCorrectionNotification>string</fullServiceAddressCorrectionNotification>
    </FullServiceNixieDetailNotification>
  </soap12:Body>
</soap12:Envelope>

回复:

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"
       xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <notificationResponse
       xmlns="http://www.usps.com/postalone/services/POCustomerMailXMLServices">string</notificationResponse>
  </soap12:Body>
</soap12:Envelope>

如您所见,我的东西被包裹在一个额外的元素中,我需要摆脱它。不幸的是,我不知道该怎么做。我的网络服务代码如下:

Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel
Imports System.Data.SqlClient

Public Structure AuthenticationInfoType
    Dim UserID As String
    Dim Password As String
End Structure

' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
' <System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://idealliance.org/maildat/Specs/md091/mailxml70C/mailxml")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class USPSMailXML
    Inherits System.Web.Services.WebService  

    <WebMethod()> _
    Public Function FullServiceNixieDetailNotification(ByVal AuthenticationInfo As AuthenticationInfoType, ByVal fullServiceAddressCorrectionNotification As String) As String

        'Some code here

        Return "MyResponse"

    End Function

【问题讨论】:

    标签: vb.net web-services asmx


    【解决方案1】:

    在回答实际问题之前先做一些前期准备。

    1. 您应该做的第一件事是远离 ASMX 并使用 WCF。如果您还不了解 WCF,那么将为您提供一个学习曲线。但我猜——不要误会——你并不是真正的 ASMX 专家。如果是这样,请不要花时间成为 ASMX 专家,这是昨天的技术;花一些时间学习 WCF。这对您和您的公司都更好。

    2. 只是为了弄清楚术语,您显示的前两个片段既不是 ASMX,也不是 WSDL。它们是实际的线路级消息。

    3. 无论您选择哪种实现技术,让我告诉您,您显示的传入和传出消息示例非常奇怪。首先,它不符合 WSI BP1.0:传入的消息元素未包装在顶级元素中。为什么不?然而,响应消息 包裹在顶层元素中。为什么?这种不一致似乎是任意的。此外,元素名称都是 TitleCase,除了一个 -- fullServiceAddressCorrectionNotification,它使用 camelCase。为什么?此外,传入消息是 USPS 命名空间,但参数使用空命名空间。嗯? 那个是谁做的?这是合法的,但似乎 vvvverrrry 很奇怪。最后,响应上的 xml 命名空间与传入消息上的 xml 命名空间完全不同。 (我可以想象最后一个很好的理由)。我猜你不负责设计消息。但这些不一致对我来说是一个危险信号。这就是我所说的 jalopy 消息设计。


    好的,所有这些都已经解决了......

    有一种方法可以在 ASMX 中使用 SoapDocumentMethodAttribute 和 XmlElement 属性的战略布局以及现有的 WebMethod 属性来塑造请求和响应。 SoapDocumentMethodAttribute 使您可以访问旋钮和控制杆,以指定传入和传出消息的元素名称和命名空间。

    这应该让你非常接近:

    <%@
      WebService
      Language="VB"
      Class="USPSMailXML"
    %>
    
    Imports System
    Imports System.Web.Services
    Imports System.Web.Services.Protocols
    Imports System.ComponentModel
    Imports System.Diagnostics
    Imports System.Xml.Serialization
    
    
    Public Structure AuthenticationInfoType
        <XmlElement(Namespace := "")> _
        Dim UserID As String
        <XmlElement(Namespace := "")> _
        Dim Password As String
    End Structure
    
    
    Public Structure NixieResponse
        <XmlElement("FullServiceNixieDetailNotificationResult")> _
        Dim Message As String
    End Structure
    
    
    ' Must not claim WSI compliance; there are multiple toplevel elements in the Request body
    '
    '<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
    <System.Web.Services.WebService(Namespace:="http://idealliance.org/maildat/Specs/md091/mailxml70C/mailxml"), _
           System.Web.Services.WebServiceBinding(ConformsTo := WsiProfiles.None), _
           ToolboxItem(False)> _
    Public Class USPSMailXML
        Inherits System.Web.Services.WebService
    
        <WebMethod(), _
         SoapDocumentMethod( _
                            Action := "", _
                            RequestElementName := "AuthenticationInfo", _
                            ResponseElementName := "FullServiceNixieDetailNotificationResponse", _
                            RequestNamespace := "http://www.usps.com/postalone/services/UserAuthenticationSchema", _
                            ResponseNamespace := "http://idealliance.org/maildat/Specs/md091/mailxml70C/mailxml", _
                            Use := System.Web.Services.Description.SoapBindingUse.Literal, _
                            ParameterStyle := System.Web.Services.Protocols.SoapParameterStyle.Bare)> _
        Public Function FullServiceNixieDetailNotification(ByVal AuthenticationInfo As AuthenticationInfoType, _
                                                           <XmlElement(Namespace := "http://www.usps.com/postalone/services/POCustomerMailXMLServices")> _
                                                           ByVal fullServiceAddressCorrectionNotification As String) _
                  As  <XmlElement("FullServiceNixieDetailNotificationResponse")> NixieResponse
    
            Dim r As New NixieResponse
            r.Message = "My Response"
    
            Return r
    
        End Function
    
    End Class
    

    我必须将其标记为 ParameterStyle = Bare,因为传入的消息有 2 个顶级元素。这意味着传出消息也是裸露的,在您的情况下这不是您想要的。因此,传出的消息,它只是一个字符串 - 我必须将它包装成一个结构,以便按照您显示的方式获得形状。

    我已经评论了传入和传出消息的设计。如果消息设计更“理智”,则其中一些扭曲是不必要的。

    【讨论】:

    • 谢谢,你说得对。我不是 Web 服务、ASMX 或 WCF 方面的专家。我的专长是应用程序开发。这是我们公司的第一个 Web 服务实施。我们熟悉 WCF,但管理层指示我不要实施它。你的代码让我到达了我需要的地方。感谢您花时间发布该内容,它对我很有帮助。
    【解决方案2】:

    根据 XMLspy,您的版本是正确的。这是它生成的请求:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
        xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <SOAP-ENV:Body>
            <m:AuthenticationInfo 
                xmlns:m="http://www.usps.com/postalone/services/UserAuthenticationSchema">
                <UserId>String</UserId>
                <UserPassword>String</UserPassword>
            </m:AuthenticationInfo>
            <m2:fullServiceNixieDetailQuery 
                xmlns:m2="http://www.usps.com/postalone/services/POAppointmentServices20">
                String
            </m2:fullServiceNixieDetailQuery>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

    请注意,身份验证“标头”和查询位于两个不同的命名空间中。

    【讨论】:

    • 桑德斯,在我看来这不是“正确性”的问题。他有一些他需要遵守的目标消息格式。他需要提供将接受请求并以这些格式生成响应的 ASMX 代码。示例消息服务器作为非正式 WSDL。
    • OBTW,如果这些样本来自 USPS,那么它们就是可疑的。在支持 XML 方面,他们的记录很糟糕。他们很早就进入了这个领域,在 SOAP 之前,然后直到最近才改变。
    猜你喜欢
    • 2016-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多