I need to build a service capable of receiving SOAP messages and re-route those to a REST microservice.
The message sender cannot be modified but my service can (and it must I guess): I decided to build an ASP.NET ASMX WebService because it seemed the most straightforward solution to handle SOAP messages;
With that said I'm facing a specific issue during my development and my researches couldn't help me to solve it (please consider that I started my career as a developer not more than 5 years ago so my knowledge over SOAP webservices in dotnet is pretty insufficient):
The object I'll be receiving will have the following structure:
sender-example.xml
<s:Envelope xmlns:a="http://<sender-website-containing-this-schema>/soap/encoding"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="<SOME_STRING_WITH_THIS_FORMAT>">
<s:Body>
<ns1:EndpointRelatedFunction>
<data></data>
...
The webservice I wrote till now is not that different from what VisualStudio generates when adding a new asmx file (I'll report it for completeness):
ASMXWebService.asmx.cs
namespace ASMXWebService
{
/// <summary>
/// Summary description for ProxySOAP
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class ASMXWebService : WebService
{
[WebMethod]
public string EndpointRelatedFunction(object data)
{
return "Hello World";
}
}
}
This portion of code generates an enpoint that can receive xmls messages as the one that follows:
<?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://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<EndpointRelatedFunction xmlns="http://tempuri.org/">
<data />
</EndpointRelatedFunction>
</soap:Body>
</soap:Envelope>
My problem is that when I try to send the object that this service will have to receive (I'm using postman) I get the an "500 Internal server error" with the following error message:
soap:VersionMismatchSystem.Web.Services.Protocols.SoapException: Possible SOAP version mismatch:
Envelope namespace <http://<sender-website-containing-this-schema>/soap/encoding> was
unexpected. Expecting http://schemas.xmlsoap.org/soap/envelope/. at
System.Web.Services.Protocols.SoapServerProtocol.CheckHelperVersion() at
System.Web.Services.Protocols.SoapServerProtocol.Initialize() at
System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context,
HttpRequest request, HttpResponse response, Boolean& abortProcessing)
I guess I should add something on the top of
public class ASMXWebService : WebService
but I have no idea what it would be.
Solving this issue might solve my other problems (I'm guessing will be my next problems) and those might be:
- How can I define those custom prefix namespaces (like ':a' or ':ns1') in the asmx code?
- What could be the value for xmlns:ns1 with that strange format? (I would expect only paths as namespace value).
I'm open to redefine the whole structure of my service (anything but having to use WCF, if it's the best way tell me why and show me how please).
UPDATE:
Apparently as long as the namespace URI is reachable the webservice is able parse the xml correctly without having to add anything to the ASMXWebService.asmx.cs file;
So that error was likely related to the fact that on the network I was I couldn't reach the first namespace's URI.
The problem I'm facing now is related to the "ns1" namespace, it does not seem an URI so I've contacted the sender service maintainers to get infos on whatever that is.
UPDATE 2:
Apparently the ns1 namespace was just what "http://tempuri.org/" was in my ASMXWebService.asmx.cs file; Changing "http://tempuri.org/" to ns1 namespace does still give an error because the webservice is not able to deserialize the xml body (is expecting
<EndpointRelatedFunction xlmns="WEB_SERVICE_NAMESPACE_THAT_PREVIOUSLY_WAS_TEMPURI">
insted of <ns1:EndpointRelatedFunction>).
I'm trying to solve the problem by intercepting the xml message before it gets deserialized and change it in order to work with the xml schema that my webservice is using (a bit odd considering that those schemas were given by sender's maintainers so the example they provided me should have been generated by that same xml schema).
To do so I'm using SoapExtension (https://learn.microsoft.com/en-us/dotnet/api/system.web.services.protocols.soapextension?view=netframework-4.8.1).