SoapCore Documentation

repository·develop·Indexed 22 days ago

https://github.com/digdes/soapcore

A SOAP protocol middleware for ASP.NET Core that enables hosting SOAP services in modern .NET environments. It supports ref out parameters, exceptions, and compatibility with legacy WCF/WS clients. Features include support for custom ISoapCoreSerializer implementations, external WSDL/XSD schemas via WsdlFileOptions, and pipeline extensions through MessageInspectors, OperationInvokers, and SoapMessageProcessors.

Tokens
2.3K
Snippets
8
Records
9
Agent score
27%

What's inside SoapCore

  1. Extend the SoapCore pipeline

    develop

    You can extend the SoapCore pipeline by registering additional components in ConfigureServices:

    • services.AddSoapMessageInspector(): Adds a custom MessageInspector (similar to WCF's IDispatchMessageInspector).
    • services.AddSingleton<MyOperatorInvoker>(): Adds a custom OperationInvoker to override service operation invocation (e.g., for logging or exception handling).
    • services.AddSoapMessageProcessor(): Adds a custom SoapMessageProcessor middleware to inspect or modify messages and HttpContext on the way in and out.
  2. Use a custom implementation of Serialization

    develop

    You can implement ISoapCoreSerializer to create a custom serializer for the SOAP body. To use it, register your implementation via AddCustomSoapMessageSerializer<T> in ConfigureServices and specify it in the endpoint options using UseCustomSerializer<T>.

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSoapCore();
        services.TryAddSingleton<ServiceContractImpl>();
        services.AddCustomSoapMessageSerializer<CustomeBodyMessageSerializerImpl>();
        services.AddMvc();
    }
    
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseEndpoints(endpoints => {
            endpoints.UseSoapEndpoint<ServiceContractImpl>(soapCoreOptions =>
            {
                soapCoreOptions.Path = "/ServicePath.asmx";
                soapCoreOptions.UseCustomSerializer<CustomeBodyMessageSerializerImpl>();
                soapCoreOptions.SoapSerializer = SoapSerializer.DataContractSerializer;
            });
        });
    }
  3. Configure SoapCore in ASP.NET Core (Endpoint Routing)

    develop

    For ASP.NET Core 3.1 or higher using endpoint routing (the default), register the service in ConfigureServices and map the endpoint in Configure using UseSoapEndpoint<T>.

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSoapCore();
        services.TryAddSingleton<ServiceContractImpl>();
        services.AddMvc();
    }
    
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseRouting();
    
        app.UseEndpoints(endpoints => {
            endpoints.UseSoapEndpoint<ServiceContractImpl>(opt =>
            {
                opt.Path = "/ServicePath.asmx";
                opt.SoapSerializer = SoapSerializer.DataContractSerializer;
            });
        });
    }
  4. Configure SoapCore in ASP.NET Core 2.1

    develop

    For ASP.NET Core 2.1 (or .NET Standard 2.0 compliant platforms), use the following configuration pattern:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSoapCore();
        services.TryAddSingleton<ServiceContractImpl>();
        services.AddMvc();
    }
    
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseSoapEndpoint<ServiceContractImpl>("/ServicePath.asmx", new SoapEncoderOptions());
    }
  5. Access custom HTTP headers in a SoapCore service using IServiceOperationTuner

    develop

    To access HTTP headers within your service implementation, implement IServiceOperationTuner and register it using AddSoapServiceOperationTuner. The Tune method provides access to the HttpContext.

    public class MyServiceOperationTuner : IServiceOperationTuner
    {
        public void Tune(HttpContext httpContext, object serviceInstance, SoapCore.ServiceModel.OperationDescription operation)
        {
            if (operation.Name.Equals("SomeOperationName"))
            {
                MyService service = serviceInstance as MyService;
                if (httpContext.Request.Headers.TryGetValue("some_parameter", out var paramValue))
                {
                    service.SetParameterForSomeOperation(paramValue[0]);
                }
            }
        }
    }
    
    // In Startup.cs
    services.AddSoapServiceOperationTuner(new MyServiceOperationTuner());
  6. Use external WSDL / XSD schemas

    develop

    Instead of generating service descriptions from code, you can load them from files on the server using WsdlFileOptions.

    1. Add a FileWSDL section to your appsettings.json:
    "FileWSDL": {
      "UrlOverride": "",
      "SchemeOverride": "",
      "VirtualPath": "",
      "WebServiceWSDLMapping": {
        "Service.asmx": {
          "UrlOverride": "Management/Service.asmx",
          "WsdlFile": "snapshotpull.wsdl",
          "SchemaFolder": "Schemas",
          "WsdlFolder": "Schemas"
        }
      }
    }
    1. Load the settings and pass them to UseSoapEndpoint in Startup.cs:
    var settings = Configuration.GetSection("FileWSDL").Get<WsdlFileOptions>();
    settings.AppPath = env.ContentRootPath;
    
    app.UseSoapEndpoint<ServiceContractImpl>("/Service.asmx", new SoapEncoderOptions(), SoapSerializer.XmlSerializer, false, null, settings);
  7. Add additional namespace declarations to the SOAP Envelope

    develop

    You can add custom XML namespace attributes (e.g., xmlns:myNS="...") to the SOAP Envelope by populating the AdditionalEnvelopeXmlnsAttributes dictionary on SoapEncoderOptions within the UseSoapEndpoint configuration.

    endpoints.UseSoapEndpoint<IService>(opt =>
    {
        opt.Path = "/ServiceWithAdditionalEnvelopeXmlnsAttributes.asmx";
        opt.AdditionalEnvelopeXmlnsAttributes = new Dictionary<string, string>()
        {
            { "myNS", "http://schemas.someting.org" },
            { "arr", "http://schemas.microsoft.com/2003/10/Serialization/Arrays" }
        };
    });
  8. Implement ISoapMessageProcessor to inspect/modify messages

    develop

    Use AddSoapMessageProcessor to intercept the SOAP message. This allows you to read the body, modify it, and pass it along the pipeline or return a custom response.

    services.AddSoapMessageProcessor(async (message, httpcontext, next) =>
    {
        var bufferedMessage = message.CreateBufferedCopy(int.MaxValue);
        var msg = bufferedMessage.CreateMessage();
        var reader = msg.GetReaderAtBodyContents();
        var content = reader.ReadInnerXml();
    
        // Pass the original message or a new one to the rest of the pipe
        var originalMessage = bufferedMessage.CreateMessage();
        var responseMessage = await next(message);
    
        return responseMessage;
    });