Dotnet core with SOAP service

↘锁芯ラ 提交于 2021-02-07 09:34:51

问题


We have a ASP.NET Core system and we need to connect to another webservice using SOAP (we received the WSDL from the customer).

In the past, we should have use the "add service reference" using WCF options in Visual Studio.

For dotnet core projects, the options is no more available but there are several options to get the same solutions:

Use SvcUtil in the command line or install the plugin here 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/ to generate the .cs files

Both solutions need to be used in conjunction with these nuget packages https://github.com/dotnet/wcf

So my question: Is there another solution than using WCF to access a SOAP service in C#?


回答1:


You can use a tool like Soap UI to get the actual format of the xml request.

You can then execute the request using a WebRequest - something like the code below. As far as I know there is no way to auto-generate the classes so you would have to do the deserialization yourself:

    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;
    }



回答2:


I was able to achieve this with the use of WSDL.exe to generate your classes (same as what a legacy WCF add service reference would do), sending the request (as if WCF), adding a message inspector, and in the BeforeSendRequest method catch the generated Message object, then cancelling the WCF web request (as this request would fail anyway since it's not supported in dotnet Core). This generates the necessary objects for you to send.

So then I just created a dotnet core HttpClient object, with the corresponding Handler, and send the 'WCF generated' request object.

Could probably get some code samples if this is not clear enough.



来源:https://stackoverflow.com/questions/44966560/dotnet-core-with-soap-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!