DigDes / SoapCore

SOAP extension for ASP.NET Core
MIT License
996 stars 376 forks source link

Support for two different soap versions at once #723

Closed andersjonsson closed 2 years ago

andersjonsson commented 3 years ago

I'm in the middle of porting https://api.legaonline.se/rentalApi.asmx?wsdl to SoapCore. It has mostly been smooth sailing.

Our api has support for both soap11 and soap12. As you can see in https://api.legaonline.se/rentalApi.asmx?wsdl for every soap:operation there is a matching soap12:operation. It's the same with binding etc.

If I add multiple SoapEncoderOptions in UseSoapEndpoints I can get both kinds of klients to work, but the wsdl doesn't contain both soap:operation and soap12:operation. Just one or the other, depending on which SoapEncoderOptions is first in the list.

This has been the source of intermittent errors where one of our clients suddenly is convinced that our new api doesn't support soap12.

I can see, in MetaBodyWriter, that it's only called with one MessageVersion, even if your api supports multiple versions. Is there a way to extend MetaBodyWriterand fix this on my end, or would the default MetaBodyWriter need to be patched?

Super happy about my progress so far and I am really impressed with this project. It made a seemingly impossible task (almost) easy :)

andersjonsson commented 2 years ago

When I use postman to post a soap12 envelope I can provoke the error reliably: If I declare the SoapEncoderOptions in this order:

opt.EncoderOptions = new[] { 
new SoapEncoderOptions() { MessageVersion = System.ServiceModel.Channels.MessageVersion.Soap11 }, 
new SoapEncoderOptions() { MessageVersion = System.ServiceModel.Channels.MessageVersion.Soap12WSAddressing10 } 
};

I get the following error message

<?xml version="1.0" encoding="utf-8"?>
<prefix3:Envelope xmlns:prefix3="http://schemas.xmlsoap.org/soap/envelope/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <prefix3:Body>
        <prefix3:Fault>
            <faultcode>s:Client</faultcode>
            <faultstring>The envelope version of the incoming message (Soap12 (http://www.w3.org/2003/05/soap-envelope)) does not match that of the encoder (Soap11 (http://schemas.xmlsoap.org/soap/envelope/)). Make sure the binding is configured with the same version as the expected messages. (Parameter 'reader')</faultstring>
        </prefix3:Fault>
    </prefix3:Body>
</prefix3:Envelope>

but if I add soap12 before soap11 it works.

A client expecting soap11 still works with that order though. But only if I have created the service reference before my switcharoo

andersjonsson commented 2 years ago

Seems to be related to the issue fixed in #234

andersjonsson commented 2 years ago

IsContentTypeSupported in ProcessOperation fails, so that it just uses the first encoder. Postman didn't have a charset defined. The fallback then preferred the first Encoding (soap11) over just trusting the Content-Type (application/soap+xml)

If i changed the ContentType to application/soap+xml; charset=utf-8 it works

andersjonsson commented 2 years ago

Ok, so this is two separate issues. One is that the wsdl doesn't include all supported messageversions and one is that fallback for the encoder uses the first one, even if the messageversions doesn't match.

andersjonsson commented 2 years ago

I'll close this issue and open new ones

mmasaaf commented 1 year ago

Hello , this solution not work : Based on the SOAP request, I want my service to work with both SOAP versions.

     `   var encodingOptions = new[]
        {
            new SoapEncoderOptions() { MessageVersion = System.ServiceModel.Channels.MessageVersion.Soap12WSAddressing10 },

          new SoapEncoderOptions() { MessageVersion = System.ServiceModel.Channels.MessageVersion.Soap11 },
        };

        app.UseEndpoints(endpoints =>
        {     
            endpoints.UseSoapEndpoint<IObjetsSpecifiquesService>("/ObjetsSpecifiquesService.asmx", encodingOptions

        SoapSerializer.XmlSerializer);
        });`
betmix-matt commented 7 months ago

Yeah I'm getting the following error when I send a Soap12 encoded message with the following configuration:

The envelope version of the incoming message (Soap12 (http://www.w3.org/2003/05/soap-envelope)) does not match that of the encoder (Soap11 (http://schemas.xmlsoap.org/soap/envelope/)). Make sure the binding is configured with the same version as the expected messages. (Parameter 'reader')
        var encodingOptions = new SoapEncoderOptions[]
        {
            new () { MessageVersion = MessageVersion.Soap11 },
            new () { MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None) },
        };
        configure.UseEndpoints(app =>
        {
            app.UseSoapEndpoint<GwsServiceImpl>("/Service.asmx", encodingOptions, SoapSerializer.XmlSerializer, true);
        });

I can find no way to support two different soap versions from the same endpoint.

andersjonsson commented 7 months ago

Are you setting the correct content-type? For Soap1.2 the content-type needs to be application/soap+xml

I’m my case some clients didn’t set the content-type correctly, so I use a middleware to inspect the incoming payload and set correct content-type if contains a soap1.2 envelope.

I’ve been live with that service since late 2021. Both soap versions work