web-dev-qa-db-ja.com

.netにwsdlなしでWebサービスを呼び出す方法

Wsdlもasmxも提供しないサードパーティのWebサービスに接続する必要があります。サービスのURLは http://server/service.soap です。

生のサービス呼び出しについて この記事 を読みましたが、これが私が探しているものかどうかはわかりません。

また、私はwsdlファイルを要求しましたが、存在しない(そして存在しない)と言われました。

私は.net 2.0でC#を使用しており、3.5にアップグレードできません(したがって、まだWCFはありません)。サードパーティはJavaを使用していると思います。これは、サードパーティが提供した例です。

前もって感謝します!

[〜#〜] update [〜#〜]URLを参照するときにこの応答を取得します。

<SOAP-ENV:Envelope>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>
Cannot find a Body tag in the enveloppe
</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
23
MaLKaV_eS

さて、ようやくこれが機能するようになったので、使用するコードをここに記述します。 (.Net 2.0、およびWebサービスから取得するwsdlはありません)。

まず、HttpWebRequestを作成します。

public static HttpWebRequest CreateWebRequest(string url)
{
    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
    webRequest.Headers.Add("SOAP:Action");
    webRequest.ContentType = "text/xml;charset=\"utf-8\"";
    webRequest.Accept = "text/xml";
    webRequest.Method = "POST";
    return webRequest;
}

次に、Webサービスを呼び出し、必要なすべての値を渡します。 XMLドキュメントからSOAPエンベロープを読み取っているので、データをStringDictionaryとして処理します。これを行うには良い方法ですが、これについては後で考えます。

public static XmlDocument ServiceCall(string url, int service, StringDictionary data)
{
    HttpWebRequest request = CreateWebRequest(url);

    XmlDocument soapEnvelopeXml = GetSoapXml(service, data);

    using (Stream stream = request.GetRequestStream())
    {
        soapEnvelopeXml.Save(stream);
    }

    IAsyncResult asyncResult = request.BeginGetResponse(null, null);

    asyncResult.AsyncWaitHandle.WaitOne();

    string soapResult;
    using (WebResponse webResponse = request.EndGetResponse(asyncResult))
    using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
    {
        soapResult = rd.ReadToEnd();
    }

    File.WriteAllText(HttpContext.Current.Server.MapPath("/servicios/" + DateTime.Now.Ticks.ToString() + "assor_r" + service.ToString() + ".xml"), soapResult);

    XmlDocument resp = new XmlDocument();

    resp.LoadXml(soapResult);

    return resp;
}

これですべてです。 GetSoapXmlを回答に追加する必要があると誰かが思った場合は、それを書き留めます。

25
MaLKaV_eS

私の意見では、SOAP WebサービスがWSDLを提供しないことの言い訳はありません。サービスによって動的に生成される必要はありません。インターネット経由で利用可能である必要はありません。しかしそこには- must WSDLである必要があります。 フロッピーディスク サムドライブ!

このサービスのプロバイダーに不満を言う能力がある場合は、そうすることをお勧めします。あなたがプッシュバックする能力を持っているなら、そうしてください。理想的には、サービスプロバイダーを切り替えて、WSDLを提供しなかったためだと伝えます。少なくとも、なぜそれが重要だと思わないのかを調べてください。

17
John Saunders

運が良ければ、それでもwsdlを入手できます。一部のWebサービスフレームワークでは、動的に生成されたWSDLを取得できます。

Axis1.xで記述されたWebサービスでは、URLを参照することにより、動的に生成されたWSDLファイルを取得できます。

閲覧するだけ

http://server/service.soap/?wsdl

これが他のフレームワークで可能かどうかはわかりません。

3
Glen

ええと、ここはトリッキーですが不可能ではありませんが、私はそれを拡張するために最善を尽くします。

あなたがする必要があるのは

  1. サードパーティサービスで処理しているオブジェクトスキーマに一致するシリアル化可能なクラスを作成します。
  2. サービスコールでSOAPActionを使用しているかどうかを確認する
  3. 要求と応答を処理できるという点でサービスを模倣するasmxを作成できるかどうかを確認します(これは、サービスが停止している場合にクライアントアプリをテストするのに適しています)
  4. 次に、ダミーサービスからサービスプロキシを作成し、サードパーティサービスを呼び出すときにサービスURLを変更できます。
  5. クライアントで何かが機能しない場合は、ダミーサービスを調整し、プロキシを再生成して、再試行できます。

私はそれを思いついたときにさらに追加しようとしますが、それはあなたが始めるのに十分なはずです。

3
Keith

参照なしで手動でWebServiceを呼び出す次のヘルパーメソッドを作成しました。

public static HttpStatusCode CallWebService(string webWebServiceUrl, 
                                            string webServiceNamespace, 
                                            string methodName, 
                                            Dictionary<string, string> parameters, 
                                            out string responseText)
{
    const string soapTemplate = 
@"<?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://www.w3.org/2003/05/soap-envelope"">
  <soap:Body>
    <{0} xmlns=""{1}"">
      {2}    </{0}>
  </soap:Body>
</soap:Envelope>";

    var req = (HttpWebRequest)WebRequest.Create(webWebServiceUrl);
    req.ContentType = "application/soap+xml;";
    req.Method = "POST";

    string parametersText;

    if (parameters != null && parameters.Count > 0)
    {
        var sb = new StringBuilder();
        foreach (var oneParameter in parameters)
            sb.AppendFormat("  <{0}>{1}</{0}>\r\n", oneParameter.Key, oneParameter.Value);

        parametersText = sb.ToString();
    }
    else
    {
        parametersText = "";
    }

    string soapText = string.Format(soapTemplate, methodName, webServiceNamespace, parametersText);


    using (Stream stm = req.GetRequestStream())
    {
        using (var stmw = new StreamWriter(stm))
        {
            stmw.Write(soapText);
        }
    }

    var responseHttpStatusCode = HttpStatusCode.Unused;
    responseText = null;

    using (var response = (HttpWebResponse)req.GetResponse())
    {
        responseHttpStatusCode = response.StatusCode;

        if (responseHttpStatusCode == HttpStatusCode.OK)
        {
            int contentLength = (int)response.ContentLength;

            if (contentLength > 0)
            {
                int readBytes = 0;
                int bytesToRead = contentLength;
                byte[] resultBytes = new byte[contentLength];

                using (var responseStream = response.GetResponseStream())
                {
                    while (bytesToRead > 0)
                    {
                        // Read may return anything from 0 to 10. 
                        int actualBytesRead = responseStream.Read(resultBytes, readBytes, bytesToRead);

                        // The end of the file is reached. 
                        if (actualBytesRead == 0)
                            break;

                        readBytes += actualBytesRead;
                        bytesToRead -= actualBytesRead;
                    }

                    responseText = Encoding.UTF8.GetString(resultBytes);
                    //responseText = Encoding.ASCII.GetString(resultBytes);
                }
            }
        }
    }

    // standard responseText: 
    //<?xml version="1.0" encoding="utf-8"?>
    //<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    //    <soap:Body>
    //        <SayHelloResponse xmlns="http://tempuri.org/">
    //            <SayHelloResult>Hello</SayHelloResult>
    //        </SayHellorResponse>
    //    </soap:Body>
    //</soap:Envelope>
    if (!string.IsNullOrEmpty(responseText))
    {
        string responseElement = methodName + "Result>";
        int pos1 = responseText.IndexOf(responseElement);

        if (pos1 >= 0)
        {
            pos1 += responseElement.Length;
            int pos2 = responseText.IndexOf("</", pos1);

            if (pos2 > pos1)
                responseText = responseText.Substring(pos1, pos2 - pos1);
        }
        else
        {
            responseText = ""; // No result
        }
    }

    return responseHttpStatusCode;
}

その後、次のコードで任意のWebサービスメソッドを呼び出すことができます。

var parameters = new Dictionary<string, string>();
parameters.Add("name", "My Name Here");

string responseText;
var responseStatusCode = CallWebService("http://localhost/TestWebService.asmx", 
                                        "http://tempuri.org/", 
                                        "SayHello", 
                                        parameters, 
                                        out responseText);
3
Andrej Benedik