Search code examples
c#web-serviceswcfsoap.net-core

Dotnet core with SOAP service


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#?


Solution

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