DigDes/SoapCore

The SOAP request header (message) is not filled in ISoapMessageProcessor (Suspected message encoding problem UTF-16)

ComradeSwarog opened this issue · 3 comments

The SOAP request header (message) is not filled in ISoapMessageProcessor (Suspected message encoding problem UTF-16)

Package version SoapCore 1.1.0.41
Asp Net Core 6

This is how I initialize SOAP the service

var builder = WebApplication.CreateBuilder(args);

var settings = new Settings();
builder.Configuration.Bind(settings);
builder.Services.AddSingleton<ISettings>(settings);

builder.Services.AddSoapCore();
builder.Services.AddScoped<emdrClientCallbackPort, EmdrCallbackService>();
builder.Services.AddSoapMessageProcessor<SingSoapMessageProcessor>();

var app = builder.Build();

app.UseRouting();

app.UseEndpoints(endpoints =>
{
    endpoints.UseSoapEndpoint<emdrClientCallbackPort>(options =>
    {
        options.Path = "/Service.wsdl";
        options.EncoderOptions = new []
        {
            new SoapEncoderOptions
            {
                MessageVersion = MessageVersion.Soap12WSAddressingAugust2004,
                WriteEncoding = Encoding.UTF8,
                OverwriteResponseContentType = true
            }
        };
        options.SoapSerializer = SoapSerializer.XmlSerializer;
        options.OmitXmlDeclaration = true;
        options.AdditionalEnvelopeXmlnsAttributes = new Dictionary<string, string>
        {
            {
                "oas", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
            },
            {
                "wsa", "http://www.w3.org/2005/08/addressing"
            },
            {
                "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
            }
        };
    });
});

This is how I implement the interface ISoapMessageProcessor

public class SingSoapMessageProcessor :ISoapMessageProcessor
{
    private readonly ISettings _settings;

    public SingSoapMessageProcessor(ISettings settings)
    {
        _settings = settings;
    }

    public async Task<Message> ProcessMessage(Message message, HttpContext context, Func<Message, Task<Message>> next)
    {
        var action = message.Headers.Action; // this value is null
        var to = message.Headers.To; // this value is null
        var messageId = message.Headers.MessageId; // // this value is null

        var responce = await next(message);

        var action2 = message.Headers.Action; // this value is null after the call next
        var to2 = message.Headers.To; // this value is null after the call next
        var messageId2 = message.Headers.MessageId; // // this value is null after the call next

But the message header is filled with parameters, but when debugging it is clear that they are encoded in UTF-16, but should be in UTF-8, since the content type of the request is HTTP = text/xml; charset=utf-8

изображение

Help me solve this problem or indicate the version of the package where this problem does not occur, thanks.

That seems odd. I don't really have the time to dive into this at the moment but I've done an overview. I don't think there is a version of the package where this doesn't occur

If you want to fix this your first stop should probably be

public Task<Message> ReadMessageAsync(Stream stream, int maxSizeOfHeaders, string contentType)
{
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
XmlReader reader;
var readEncoding = SoapMessageEncoderDefaults.ContentTypeToEncoding(contentType);
if (readEncoding == null)
{
// Fallback to default or writeEncoding
readEncoding = _writeEncoding;
}
var supportXmlDictionaryReader = SoapMessageEncoderDefaults.TryValidateEncoding(readEncoding, out _);
if (supportXmlDictionaryReader)
{
reader = XmlDictionaryReader.CreateTextReader(stream, readEncoding, ReaderQuotas, dictionaryReader => { });
}
else
{
var streamReaderWithEncoding = new StreamReader(stream, readEncoding);
var xmlReaderSettings = new XmlReaderSettings() { IgnoreWhitespace = true, DtdProcessing = DtdProcessing.Prohibit, CloseInput = true };
reader = XmlReader.Create(streamReaderWithEncoding, xmlReaderSettings);
}
Message message = Message.CreateMessage(reader, maxSizeOfHeaders, MessageVersion);
return Task.FromResult(message);
}

This is where the message gets parsed out.
There is a method in SoapMethodEncoderDefaults for parsing encoding from the content. That might be where things go wrong.
public static Encoding ContentTypeToEncoding(string contentType)
{
var charSet = MediaTypeHeaderValue.Parse(contentType).CharSet;
foreach (var charSetEncoding in CharSetEncodings)
{
if (charSetEncoding.Encoding == null)
{
continue;
}
if (charSetEncoding.CharSet == charSet)
{
return charSetEncoding.Encoding;
}
}
return null;
}

This issue is stale because it has been open for 30 days with no activity.

This issue was closed because it has been inactive for 14 days since being marked as stale.