Overriding SoapCore OnWriteBodyContents method gives error

85 Views Asked by At

I am trying to customize my SOAP response XML schema by inheriting from SoapCore's CustomMessage class. I have overriden the OnWriteBodyContents method. However, anytime I try to write the XML's Body Content, I keep getting the error below

System.InvalidOperationException: This message cannot support the operation because it has been written.
   at System.ServiceModel.Channels.Message.EnsureWriteMessageState(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.Message.WriteBodyContents(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.Message.WriteBody(XmlDictionaryWriter writer)
   at SoapApi.CustomNamespaceMessage.OnWriteBodyContents(XmlDictionaryWriter writer) in 
   SoapApi\CustomNamespaceMessage.cs:line 25
   at System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer)
   at System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter writer)
   at SoapCore.MessageEncoder.SoapMessageEncoder.WriteMessageAsync(Message message, HttpContext httpContext, PipeWriter pipeWriter)
   at SoapCore.SoapEndpointMiddleware`1.ProcessOperation(HttpContext httpContext, IServiceProvider serviceProvider)
   at SoapCore.SoapEndpointMiddleware`1.Invoke(HttpContext httpContext, IServiceProvider serviceProvider)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Below are my code snippets

public class CustomNamespaceMessage : CustomMessage
{
    private const string EnvelopeNamespace = "http://schemas.xmlsoap.org/soap/envelope/";

    public CustomNamespaceMessage() { }

    public CustomNamespaceMessage(Message message) : base(message) { }

    protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
    {
        writer.WriteStartElement("env", "Envelope", EnvelopeNamespace);
        writer.WriteAttributeString("xmlns", null, EnvelopeNamespace);
        writer.WriteAttributeString("xmlns", "ns2", null, "http://ws.webgate.bpc.ru/");
    }

    protected override void OnWriteStartBody(XmlDictionaryWriter writer)
    {
        writer.WriteStartElement("env", "Body", EnvelopeNamespace);
    }

    protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
    {
        WriteBodyContennts(writer);        
    }

    public override MessageHeaders Headers => Message.Headers;

    public override MessageProperties Properties => Message.Properties;

    public override MessageVersion Version => Message.Version;
}

In the startup, I have registered whatever I need to register

public void ConfigureServices(IServiceCollection services)
{
    services.AddSoapCore();
    services.AddAutoMapper(typeof(MappingProfile));

    //Change to Scoped for production
    services.AddScoped<ISwitchedService, SwitchedService>();
    services.AddHttpContextAccessor();

    services.AddMvc().AddXmlSerializerFormatters();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseEndpoints(endpoints =>
    {
        endpoints.UseSoapEndpoint<ISwitchedService, CustomNamespaceMessage>("/SwitchPayment.asmx", new SoapEncoderOptions(), SoapSerializer.XmlSerializer);
        endpoints.MapControllers(); 
    });
}

I have done numerous searches, but none satisfies my problem. Any help would be appreciated.

0

There are 0 best solutions below