如何在 Asp.net Core 项目中使用 SoapCore 在项目路由文件夹中公开 wsdl

哈米德·耶尔迪里姆

您的项目是用 Asp.net Core 编写的,用于部署 Rest API。但是,您的客户想要使用肥皂进行交流。如何进行改进

哈米德·耶尔迪里姆

SoapCore已经为我们做了很多事情来支持这种情况。我们将逐步更改应用于我们的 Asp.net Core 项目。

首先在 Startup.cs 中:

public void ConfigureServices(IServiceCollection services)
        {
            try
            {
                services.AddSoapServiceOperationTuner(new MyServiceOperationTuner());

                services.Configure<XApiSettings>(options =>
                {
                    options.baseurl = XApiOptions[nameof(XApi.baseurl)];
                    options.accesstokenroute = XApiOptions[nameof(XApi.accesstokenroute)];
                    options.secret = XApiOptions[nameof(XApi.secret)];
                    options.secretkey = XApiOptions[nameof(XApi.secretkey)];
                    options.grant_type = XApiOptions[nameof(XApi.grant_type)];
                    options.username = XApiOptions[nameof(XApi.username)];
                    options.password = XApiOptions[nameof(XApi.password)];
                });


                services.AddSoapCore();
                services.AddSingleton<IRESAdapterService>(new RESAdapterService(
                    Xcontroller: new XApiController(
                        services.BuildServiceProvider().GetRequiredService<IOptions<XApi>>(),
                        _corendonLogger
                        )));
                services.AddSoapExceptionTransformer((ex) => ex.Message);
            }
            catch (Exception ex)
            {
                Log.Logger.Error("ConfigureServices Message: " + ex.Message);
            }
        }

如果您希望您的应用程序可以从您部署地址的根目录访问,您可以直接键入路径“/”或将其命名为“/XX”

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ApplicationContext dbContext)
    {
        try
        {
            app.UseSoapEndpoint<IRESAdapterService>(path: "/", binding: new BasicHttpBinding(), SoapSerializer.XmlSerializer);
        }
    }

在服务器端处理请求的情况下,作为 xml 发送的数据通常为空。我们需要在 SoapCore 中进行以下改进,以便服务器可以解析请求。

public class MyServiceOperationTuner : IServiceOperationTuner
    {
        public void Tune(HttpContext httpContext, object serviceInstance, SoapCore.OperationDescription operation)
        {
            RESAdapterService service = serviceInstance as RESAdapterService;
            service.SetHttpRequest = httpContext.Request;
        }
    }

另外,满足传入请求和服务重定向到我们的控制器的接口应该写如下

[ServiceContract]
    public interface IRESAdapterService
    {
        [OperationContract]
        [XmlSerializerFormat(SupportFaults = true)]
        Task<OTA_AirAvailRS> getAvailability([FromBody]HttpRequestMessage req);
        [OperationContract]
        Task<OTA_AirPriceRS> pricing([FromBody]HttpRequestMessage req);
    }

        public class RESAdapterService : IRESAdapterService
        {
            XApiController _controller;
            public HttpRequest SetHttpRequest { get; set; }
            public RESAdapterService(XApiController XApi)
            {
                _controller = XApi;
            }

            public Task<MyRequesterClass> Method1([FromBody]HttpRequestMessage req)
            {
                return _controller.Method1(SetHttpRequest);
            }

            public Task<MyDiffRequesterClass> Method2([FromBody]HttpRequestMessage req)
            {
                return _controller. Method2(SetHttpRequest);
            }
        }

控制器正在捕获来自 Request 对象的请求,但是;现在请求对象必须通过路由器服务才能在这种情况下为 null 的未来。因此我们可以实现读取XML的代码如下

 Stream reqBody = Request?.Body;
        if (Request == null)
            reqBody = (MyRequesterClass as HttpRequest).Body;

客户端,写一个简单的框架控制台项目

通常我们通过添加代理可以创建和行走的部分来提供 wsdl 视觉工作室添加引用。(推荐案例)但在我的案例中,我决定使用 webclient 发布 xml,因为我使用了用户证书,但我不知道要发送的对象类型。使用示例如下:

static string xml = " <ReqObj xmlns='http://tempuri.org/'>"
                + "</ ReqObj >";

        static string wrapbody = @"<?xml version=""1.0"" encoding=""utf-8""?>
                    <soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" 
                        xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" 
                        xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
                        <soap:Body>
                           #
                        </soap:Body>
                    </soap:Envelope>";

        public static async Task<string> CreateSoapEnvelope()
        {
            HttpResponseMessage response = await PostXmlRequest("https://localhostorliveaddress.com");
            string content = await response.Content.ReadAsStringAsync();

            return content;
        }

        public static async Task<HttpResponseMessage> PostXmlRequest(string baseUrl)
        {
            X509Certificate2 clientCert = new X509Certificate2(@"D:\ccer\xxx.pfx", "password");
            //X509Certificate2 clientCert = GetClientCertificate();
            WebRequestHandler requestHandler = new WebRequestHandler();
            requestHandler.ClientCertificates.Add(clientCert);

            using (var httpClient = new HttpClient(requestHandler))
            {
                string wrpXmlContent = wrapbody.Replace("#", xml);
                var httpContent = new StringContent(wrpXmlContent, Encoding.UTF8, "text/xml");
                httpContent.Headers.Add("SOAPAction", "https://localhostorliveaddress.com/method1");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));

                return await httpClient.PostAsync(baseUrl, httpContent);
            }
        }

从我的用户个人商店获取客户证书

private static X509Certificate2 GetClientCertificate()
    {
        X509Store userCaStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        try
        {
            userCaStore.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection certificatesInStore = userCaStore.Certificates;
            X509Certificate2Collection findResult = certificatesInStore.
                Find(X509FindType.FindBySubjectName, "XRootCertificateOnMyUserPersonelStore", true);
            X509Certificate2 clientCertificate = null;

            if (findResult.Count == 1)
            {
                clientCertificate = findResult[0];
            }
            else
            {
                throw new Exception("Unable to locate the correct client certificate.");
            }
            return clientCertificate;
        }
        catch
        {
            throw;
        }
        finally
        {
            userCaStore.Close();
        }
    }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在Visual Studio ASP.NET Core项目中使用语义UI反应?

如何在ASP.NET Core项目中使用MStest测试Ok()结果

如何在Asp.Net Core 2.1项目中使用EF Core 2.2.4数据库

在ASP.NET 4.5项目中使用wwwroot文件夹(ASP.NET Core样式)

在测试项目中使用ASP.NET Core的ConfigurationBuilder

如何在ASP.NET Core MVC和Angular项目中使用Angular Material组件(特别是滑块)?

如何在ASP.NET Core MVC项目中使用jQuery和Ajax从视图调用api?

如何在ASP.NET Core 2.1项目中保护基于用户的文件夹和文件

如何在.net Core项目中使用SignalR Core监听Postgresql数据库?

在 asp.net core 2 项目中使用路由提供角度服务

如何在面向 net462 框架的 .Net Core 项目中使用 ConfigurationPropertyAttribute?

如何在ASP.NET MVC项目中使用.NET的GroupDocs Viewer?

在ASP.NET Core 3.0 Web API项目中使用WebApiContrib.Core.Formatter.Csv

在ASP .Net Core项目中使用.Net用户控件(.ascx)的可能性

如何在ASP.NET核心项目中使用多个gulpfile.js?

如何在ASP.NET MVC ReactJS项目中使用“导入”?

如何在ASP.NET Core项目中为MVC和SignalR配置路由?

在没有 EF Core 参考的 ASP.NET 项目中使用 EF 存储?

在ASP.NET Core项目中使用没有实体框架的SQLLite数据库

在完整的 .NET 框架上从 ASP.NET Core 项目中的 NuGet 文件夹引用 DLL

如何在 .Net Core+React 项目中创建 wwwroot 文件夹?

如何在Rider中使用F#创建ASP.NET Core WebAPI项目?

如何获取.net core项目中项目文件夹中存在的文件的相对路径

如何在ASP.NET Core项目中读取本地文件?

如何在.NET Core 2 classlib项目中使用C#从.csproj文件读取/获取PropertyGroup值?

在 Web 窗体项目中使用 .Net Core 项目

如何在ASP.NET Core(面向.NET Framework的目标)项目中引用旧程序集?

如何在Angular项目中显示保存在wwwroot(asp.net core)中的图像

如何在ASP.NET MVC 5项目中使用jquery-validation-unobtrusive验证文件的大小?