Веб-сервис .NET. (ASMX) Как я могу сформировать сообщения запроса и ответа? - PullRequest
2 голосов
/ 19 декабря 2009

Я создаю веб-сервис для приема уведомлений от компании. Компания сообщила мне, что сервис неправильно структурирован, и предоставила мне .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 ]

5 голосов
/ 19 декабря 2009

Соедините предварительные вещи, прежде чем перейти к актуальному вопросу.

  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 элемента верхнего уровня. Это означает, что исходящее сообщение также было голым, что в вашем случае НЕ то, что вы хотите. Поэтому исходящее сообщение, которое является просто строкой - мне пришлось обернуть его в структуру, чтобы придать форму, как вы показали.

Я уже прокомментировал оформление входящих и исходящих сообщений. Некоторые из этих искажений не были бы необходимы, если бы дизайн сообщения был более «вменяемым».

1 голос
/ 28 декабря 2009

Согласно 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>

Обратите внимание, что заголовок аутентификации и запрос находятся в двух разных пространствах имен.

...