C# 如何在 .net 中调用没有 wsdl 的 Web 服务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1277212/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:34:31  来源:igfitidea点击:

How to call a web service with no wsdl in .net

c#.netweb-servicessoapwsdl

提问by MaLKaV_eS

I have to connect to a third party web service that provides no wsdl nor asmx. The url of the service is just http://server/service.soap

我必须连接到不提供 wsdl 或 asmx 的第三方 Web 服务。服务的 url 只是http://server/service.soap

I have read this articleabout raw services calls, but I'm not sure if this is what I'm looking for.

我已阅读有关原始服务调用的这篇文章,但我不确定这是否是我要查找的内容。

Also, I've asked for wsdl files, but being told that there are none (and there won't be).

另外,我要求提供 wsdl 文件,但被告知没有(并且不会有)。

I'm using C# with .net 2.0, and can't upgrade to 3.5 (so no WCF yet). I think that third party is using java, as that's the example they have supplied.

我在 .net 2.0 中使用 C#,并且无法升级到 3.5(所以还没有 WCF)。我认为第三方正在使用 java,因为这是他们提供的示例。

Thanks in advance!

提前致谢!

UPDATEGet this response when browsing the 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>

采纳答案by MaLKaV_eS

Well, I finally got this to work, so I'll write here the code I'm using. (Remember, .Net 2.0, and no wsdl to get from web service).

好吧,我终于让它工作了,所以我会在这里写我正在使用的代码。(请记住,.Net 2.0,并且没有 wsdl 可以从 Web 服务中获取)。

First, we create an HttpWebRequest:

首先,我们创建一个 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;
}

Next, we make a call to the webservice, passing along all values needed. As I'm reading the soap envelope from a xml document, I'll handle the data as a StringDictionary. Should be a better way to do this, but I'll think about this later:

接下来,我们调用 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;
}

So, that's all. If anybody thinks that GetSoapXml must be added to the answer, I'll write it down.

所以,仅此而已。如果有人认为必须将 GetSoapXml 添加到答案中,我会写下来。

回答by Glen

If you're lucky you could still get the wsdl. Some web service frameworks allow you to retrieve a dynamically generated WSDL.

如果幸运的话,您仍然可以获得 wsdl。某些 Web 服务框架允许您检索动态生成的 WSDL。

Web Services written with Axis1.x allow you to retrieve a dynamically generated WSDL file by browsing to the URL.

使用 Axis1.x 编写的 Web 服务允许您通过浏览 URL 来检索动态生成的 WSDL 文件。

Just browse to

只需浏览到

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

I don't know if this is possible with other frameworks though.

我不知道这是否适用于其他框架。

回答by Keith

Hmm, tricky one here but not impossible but I'll do my best to explian it.

嗯,这里很棘手,但并非不可能,但我会尽力解释它。

What you'll need to do is

你需要做的是

  1. Create serializable classes that match the object schemas you're dealing with on the third party service.
  2. Find out if they use any SOAPAction in their service calls
  3. See if you can create an asmx which mimics their service in terms of being able to handle requests and responses (this will be good for testing your client app if their service is down)
  4. You can then create a service proxy from your dummy service and change the service url when calling the third party service.
  5. If something doesnt work in your client, then you can tweak your dummy service, re-generate the proxy and try again.
  1. 创建与您在第三方服务上处理的对象模式相匹配的可序列化类。
  2. 查明他们是否在服务调用中使用了任何 SOAPAction
  3. 看看您是否可以创建一个 asmx 来模拟​​他们的服务,以便能够处理请求和响应(如果他们的服务出现故障,这将有助于测试您的客户端应用程序)
  4. 然后,您可以从您的虚拟服务创建一个服务代理,并在调用第三方服务时更改服务 url。
  5. 如果某些东西在您的客户端中不起作用,那么您可以调整您的虚拟服务,重新生成代理并重试。

I will try to add more as and when I think of it but that should be enough to get you started.

当我想到它时,我会尝试添加更多内容,但这应该足以让您入门。

回答by John Saunders

In my opinion, there is no excuse for a SOAP web service to not supply a WSDL. It need not be dynamically generated by the service; it need not be available over the Internet. But there mustbe a WSDL, even if they have to send it to you on a floppy diskthumb drive!

在我看来,SOAP Web 服务没有理由不提供 WSDL。它不需要由服务动态生成;它不需要通过 Internet 提供。但是必须有一个 WSDL,即使他们必须通过软盘拇指驱动器将其发送给您!

If you have any ability to complain to the providers of this service, then I urge you to do so. If you have the ability to push back, then do so. Ideally, switch service providers, and tell these people it's because they didn't provide a WSDL. At the very least, find out why they don't think it's important.

如果您有任何能力向此服务的提供者投诉,那么我敦促您这样做。如果你有能力反击,那就这样做吧。理想情况下,切换服务提供商,并告诉这些人这是因为他们没有提供 WSDL。至少,找出他们认为这不重要的原因。

回答by Andrej Benedik

I have created the following helper method to call WebService manually without any reference:

我创建了以下辅助方法来手动调用 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;
}

You can then simply call any web service method with the following code:

然后,您可以使用以下代码简单地调用任何 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);