.NET Web服务。 (ASMX)如何塑造请求和响应消息?

时间:2009-12-18 21:27:34

标签: vb.net web-services asmx

我正在构建一个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

2 个答案:

答案 0 :(得分:4)

在得到实际问题之前先结合前面的事情。

  1. 您应该做的第一件事是远离ASMX并使用WCF。如果您还不知道WCF,那么您将有一个学习曲线。但我猜 - 并且不要采取错误的方式 - 你不是ASMX的专家。如果是这样,不要花时间成为ASMX的专家,这是昨天的技术;花一些时间学习WCF。这对你,对你的公司更好。

  2. 只是为了得到术语,你展示的前两个剪辑既不是ASMX,也不是WSDL。它们是实际的电报级消息。

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


  4. 好的,尽管如此......

    有一种方法可以在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个顶级元素。这意味着外发邮件也是Bare,在您的情况下不是您想要的。因此传出消息只是一个字符串 - 我必须将其包装到一个结构中,以便按照你展示的方式获得形状。

    我已经评论了传入和传出消息的设计。如果信息设计更“健全”,那么这些扭曲中的一些就不是必要的。

答案 1 :(得分:1)

根据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>

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