SoapCore Asp.net core 3.1 头文件

问题描述

知道如何使用 SoapCore 为我的调用添加标题吗?

到目前为止我所拥有的:

在startup.cs:
app.UseSoapEndpoint<IMyService>("/MyService.svc",new BasicHttpBinding(),SoapSerializer.DataContractSerializer);

在 IMyService

[ServiceContract]
    public interface IMyService
    {      

        [OperationContract]
        public List<SOADataGetService> GetService(string ServiceType,string ServiceName,string ServiceVersion);
        
    }

然后我的肥皂就变成这样了:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:GetService>
         <tem:ServiceType>?</tem:ServiceType>
         <tem:ServiceName>?</tem:ServiceName>
         <tem:ServiceVersion>?</tem:ServiceVersion>
      </tem:GetService>
   </soapenv:Body>
</soapenv:Envelope>

我需要像用户和密码一样输入 <soapenv:Header/>

解决方法

不要使用已经过时的 SoapCore,尝试使用 SmartSoap: https://github.com/Raffa50/SmartSoap

它也可以作为 nugetPackage 使用: https://www.nuget.org/packages/Aldrigos.SmartSoap.AspNet/

看看它,尝试一下,如果您需要进一步的支持,我很乐意为您提供帮助!

,

您可以通过实现和注册自定义 IServiceOperationTuner(如 docs 中所述)来访问 SoapCore 中的标头。

例如

public class MyServiceOperationTuner : IServiceOperationTuner
{
    public void Tune(HttpContext httpContext,object serviceInstance,SoapCore.ServiceModel.OperationDescription operation)
    {
        if (operation.Name.Equals(nameof(MyService.SomeOperationName)))
        {
            MyService service = serviceInstance as MyService;
            service.SetHttpRequest(httpContext.Request);
        }
    }
}
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.TryAddSingleton<IMyService,MyService>();
        services.TryAddSingleton<IServiceOperationTuner>(provider => new MyServiceOperationTuner());
    }
}
public class MyService : IMyService
{
    private ThreadLocal<HttpRequest> _httpRequest = new ThreadLocal<HttpRequest>() { Value = null };

    public void SetHttpRequest(HttpRequest request)
    {
        _httpRequest.Value = request;
    }

    public string SomeOperationName()
    {
        var soapHeader = GetHeaderFromRequest(_httpRequest.Value)
        return $"SOAP Header: {soapHeader}";
    }

    private XmlNode GetHeaderFromRequest(HttpRequest request)
    {
        var bytes = (request.Body as MemoryStream)?.ToArray();
        if (bytes == null)
        {
            // Body missing from request
            return null;
        }

        var envelope = new XmlDocument();
        envelope.LoadXml(Encoding.UTF8.GetString(bytes));

        return envelope.DocumentElement?.ChildNodes.Cast<XmlNode>().FirstOrDefault(n => n.LocalName == "Header");
    }
}