0

特定のクライアント用に ASP.NET Web サービス (WCF ではない) を開発しています。これは、クライアントで何も変更できない状況の 1 つです。

クライアントは次の XML を送信してメソッドを要求します。

<?xml version="1.0" encoding="UTF-8"?>
<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"
                   xmlns:cometxsd="http://werk-ii.de/soap/comet/Schema"
                   xmlns:comet="http://werk-ii.de/soap/comet"
                   xmlns:xop="http://www.w3.org/2004/08/xop/include"
                   xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
                   xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                   xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
                   xmlns:xmime5="http://www.w3.org/2005/05/xmlmime"
                   xmlns:ns1="http://soap.comet.werkii.com/">
  <SOAP-ENV:Body>
    <ns1:login xsi:type="ns1:login">
      <user>myusername</user>
      <password>mypassword</password>
      <client>whatever</client>
      <language>de</language>
    </ns1:login>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

私のサービスは、次のような login-Method を提供します。

[WebService(Namespace = "http://soap.comet.werkii.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class CometService : WebService
{
    [WebMethod(MessageName = "login")]
    [return: XmlElement("return")]
    public LoginResult Login (string user, string password, string client, string language)
    {
        return new LoginResult() {
            ResultCode = 0,
            SessionId = user + "-" + password + "-" + client + "-" + language
        };
    }
}

public class LoginResult
{
    [XmlElement("resultCode")]
    public int ResultCode { get; set; }

    [XmlElement("sessionId")]
    public string SessionId { get; set; }
}

サービスを開始すると、リクエストとして送信する必要がある SOAP 1.1 コードが表示されます。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <login xmlns="http://soap.comet.werkii.com/">
      <user>string</user>
      <password>string</password>
      <client>string</client>
      <language>string</language>
    </login>
  </soap:Body>
</soap:Envelope>

別のテスト クライアント (PHP で作成したもの) からこのコードを使用すると (サービスから指示されたとおり)、すべて正常に動作し、結果が得られます。しかし、最初からコードを送信すると (実際のクライアントが送信するもの)、メソッドが呼び出されますが、4 つの引数はすべて nullです。

XML の観点から見ると、私の意見では、両方の要求は同じです。唯一の違いは、名前空間が定義されている場所と、要素が ns1 プレフィックスを使用しているかどうかです。サービスがそれを XML として読み取る場合、これは何の違いもありません。たぶん私は間違っています。

おそらく、最初の XML の 4 つの引数は、メソッド (ns1) とは異なる名前空間 (none) を持っています。それがすべての引数が null である理由でしょうか? 引数のみの名前空間を変更するにはどうすればよいですか?

XML のメソッド行のみを変更すると (終了タグと終了タグも置き換えます) <ns1:login xsi:type="ns1:login"><login xmlns="http://soap.comet.werkii.com/">動作します! 名前空間はルート要素で適切に定義されていますが、メソッド要素が名前空間プレフィックスを使用している場合、サービスは私の要求を理解していないようです。

サービスが期待する XML 形式を変更するために、次のことを試しました。

  • System.Web.Services.Protocols.SoapDocumentMethodAttribute - まったく効果なし
  • ここに示す XmlNamespaceDeclarationsAttribute - サービス クラスやメソッドではなく、複雑な型を操作するために作成されているため、機能しないようです

問題は、サービスに最初の例の XML を受け入れるように指示するにはどうすればよいかということです。

4

1 に答える 1

1

パラメータは属性を持つこともできます:

public LoginResult Login (
    [XmlElement(Namespace = "")] string user,
    [XmlElement(Namespace = "")] string password,
    [XmlElement(Namespace = "")] string client,
    [XmlElement(Namespace = "")] string language)
{
    return new LoginResult() {
        ResultCode = 0,
        SessionId = user + "-" + password + "-" + client + "-" + language
    };
}

これが、パラメーターをグローバル名前空間に配置するソリューションです。問題は解決しました。

于 2013-11-20T10:04:36.577 に答える