c# - 如何使用旧的 WSDL+XSD 和当前的 Web 服务位置在 C# 中进行 SOAP 调用?

标签 c# web-services soap wsdl

我的问题与此类似:need to call soap ws without wsdl除了我的应用程序不使用 Spring,所以答案没有帮助。

这是我所拥有的:

  • 只接受 SOAP 请求的网络服务
  • Web 服务的当前端点 URL
  • 一个过时的 wsdl 和 xsd 文件
  • 过时的示例 SOAP 请求文件

我需要做的是:

  • 使用上述的某种组合成功发出 SOAP 请求。

我尝试从两个不同的角度来解决这个问题,但到目前为止还没有成功。我的背景是熟悉使用 POST 和 GET 的 Web 服务,但不熟悉 SOAP。谷歌搜索“C# SOAP”后,我编写了以下代码:

    void soap(String xmlfile)
{
    Stream outputStream = null;
    StreamReader reader = null;
    WebResponse response = null;

    try
    {
        string text = System.IO.File.ReadAllText(xmlfile);

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://misapi.ercot.com/2007-08/Nodal/eEDS/EWS");
        request.PreAuthenticate = true;

        X509Certificate ercotCert = X509Certificate.CreateFromCertFile("D:\\Amigo\\WebSite1\\Nodal_Test_Cert.cer");
        request.ClientCertificates.Clear();
        request.ClientCertificates.Add(ercotCert);

        ServicePointManager.ServerCertificateValidationCallback +=
            new System.Net.Security.RemoteCertificateValidationCallback(customValidation);

        request.Credentials = CredentialCache.DefaultNetworkCredentials;

        // I don't actually have a SOAPAction, but have tried adding a fake one just to see
        //request.Headers.Add("SOAPAction", "http://www.ercot.com/Nodal/Payload");

        request.Method = "POST";
        request.ContentType = "text/xml;charset=\"utf-8\"";
        request.ContentLength = text.Length;

        StreamWriter writer = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
        writer.Write(text);
        writer.Close();

        response = request.GetResponse();
        outputStream = response.GetResponseStream();

        reader = new StreamReader(outputStream);
        Response.Write(reader.ReadToEnd());
    }
    catch (WebException e)
    {
        // This is where it ends up, with Status="ProtocolError"
    }
    catch (System.Web.Services.Protocols.SoapException soapE)
    {
        // Never gets in here
    }
    catch (Exception e)
    {
        // Never gets in here
    }
    finally
    {
        if (outputStream != null)
            outputStream.Close();
        if(reader != null)
            reader.Close();
        if(response != null)
            response.Close();
    }
}

private static bool customValidation(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error)
{
    return true;
}

这会产生 500 内部服务器错误。它抛出一个不包含其他消息或内部异常的 WebException,但状态为“ProtocolError”。我尝试了其他排列方式,包括使用 XmlDocument 和其他内容类型,但都没有奏效。

我尝试过的另一件事是在 Visual Studio 中使用“添加 Web 引用”。放入端点 URL 不起作用并给出 soap 错误。相反,如果我指向我过时的 wsdl 的本地副本,那么它会添加 WebReference 但不会让我使用它,因为有许多我无法更正的错误。我的猜测是,这些错误是由于 wsdl 已过时,例如 namespace 不匹配或无法在包含的 URL 中找到内容。如果我将这些 URL 替换为当前的 Web 服务端点 URL,它仍然不起作用。

如果有人能指出我的代码中的问题,或者指导我如何使“添加 Web 引用”正常工作,我将不胜感激!

提前致谢!

最佳答案

SOAP 只是您发布到服务的负载的格式,仅此而已。对于字段和 namespace 等有定义的规范,并且有不同的 SOAP 版本,但实际上并没有那么多。 (除了它的用法非常冗长,但这是另一个话题。)

您需要从当前的 WSDL 开始。如果您知道您正在使用的 WSDL 已过时,则意味着 Web 服务期望(必需)或可以使用(可选)的内容与您的定义不同。 WSDL 是您进入 web 服务的契约(Contract)网关。您需要获得最新的 WSDL。

幸运的是,当我导航到 https://misapi.ercot.com/2007-08/Nodal/eEDS/EWS/?WSDL 时(这是我通过将“?WSDL”附加到 url 的末尾而得出的),在跳过证书错误之后,宾果游戏——服务使用了 WSDL。您可以 (a) 将其保存在本地,或 (b) 在构建 Web 服务客户端时直接从 Visual Studio 引用它。由于证书错误,我建议将其保存在本地并从那里构建。

这应该可以帮助您入门。

关于c# - 如何使用旧的 WSDL+XSD 和当前的 Web 服务位置在 C# 中进行 SOAP 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2102906/

相关文章:

c# - 首先在 Entity Framework 5代码中获取子表记录而不使用 "Include"

web-services - REST 服务器、Delphi 和 Web 服务 - 需要建议

java - java代码对应的swift中的web服务请求

c# - 向 Azure Web 应用程序上托管的 SOAP WCF 添加简单的安全性

php - 如何循环 "release"内存?

c# - 在 C# 单元测试中向模拟数据库添加数据的方法

c# - MVC : Need to build my application with multiple projects

c# - .Net 4.5.1中GCLatencyMode和gcConcurrent如何交互(使用gcserver)

json - 应该如何从前端处理 Hateoas?

python - Python SOAP 库线程安全吗?