Dotnet核心与SOAP服务

时间:2017-07-07 08:52:49

标签: c# web-services wcf soap .net-core

我们有一个ASP.NET核心系统,我们需要使用SOAP连接到另一个Web服务(我们收到了客户的WSDL)。

过去,我们应该使用"添加服务参考"在Visual Studio中使用WCF选项。

对于dotnet核心项目,选项不再可用,但有几种选择可以获得相同的解决方案:

在命令行中使用SvcUtil或在此处安装插件https://blogs.msdn.microsoft.com/webdev/2016/06/26/wcf-connected-service-for-net-core-1-0-0-and-asp-net-core-1-0-0-is-now-available/以生成.cs文件

这两种解决方案都需要与这些nuget包https://github.com/dotnet/wcf

一起使用

所以我的问题:是否有另一种解决方案,而不是使用WCF来访问C#中的SOAP服务?

2 个答案:

答案 0 :(得分:3)

您可以使用Soap UI之类的工具来获取xml请求的实际格式。

然后,您可以使用WebRequest执行请求 - 类似下面的代码。据我所知,没有办法自动生成类,所以你必须自己进行反序列化:

    public async static Task<string> CallWebService(string webWebServiceUrl, 
                                string webServiceNamespace, 
                                string methodVerb,
                                string methodName, 
                                Dictionary<string, string> parameters) {
        const string soapTemplate = 
        @"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/""
                        xmlns:{0}=""{2}"">
            <soapenv:Header />
            <soapenv:Body>
                <{0}:{1}>
                    {3}
                </{0}:{1}>
            </soapenv:Body>
        </soapenv:Envelope>";

        var req = (HttpWebRequest)WebRequest.Create(webWebServiceUrl);
        req.ContentType =   "text/xml"; //"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, 
                        methodVerb, methodName, webServiceNamespace, parametersText);

        Console.WriteLine("SOAP call to: {0}", webWebServiceUrl);
        Console.WriteLine(soapText);

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

        var responseHttpStatusCode = HttpStatusCode.Unused;
        string responseText = null;

        using (var response = (HttpWebResponse)req.GetResponseAsync().Result) {
            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);
                    }
                }
            }
        }
        return responseText;
        //return responseHttpStatusCode;
    }

答案 1 :(得分:0)

我能够通过使用WSDL.exe来生成您的类(与传统WCF添加服务引用将执行的操作相同),发送请求(如同WCF),添加消息检查器,以及BeforeSendRequest方法捕获生成的Message对象,然后取消WCF Web请求(因为此请求将失败,因为它在dotnet Core中不受支持)。这会生成您发送的必要对象。

然后我刚刚创建了一个dotnet核心HttpClient对象,带有相应的Handler,并发送'WCF generated'请求对象。

如果不够清楚,可能会得到一些代码示例。