Dol*_*lph 3 .net c# wcf soap corewcf
我正在接管一个遗留的 SOAP 项目,我需要用 .NET Core 解决方案替换 SOAP 服务。我们不能更改 SOAP 客户端,因此我们不能查看 REST、GRPC 等。我查看了 SoapCore 和 CoreWCF,并且都使用 SOAP 标头用户名/密码身份验证演示,但是,我将使用 CoreWCF暂时。
现有的SOAP服务使用自定义的http状态码响应,例如在服务处理完成后以及在某些情况下出现SOAP错误时返回202。我意识到这是不正确的,但是,我们需要维护现有的业务逻辑。
我的问题是:
有许多旧的 SO 帖子提到 WebOperationContext,但是,我似乎无法在我的服务中访问它。OperationContext 似乎无法控制 HttpStatusCode。也许我错过了一些东西。IE:
WebOperationContext ctx = WebOperationContext.Current;
ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.BadRequest;
Run Code Online (Sandbox Code Playgroud)
这是我的示例项目细分:
程序.cs
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using System.Diagnostics;
namespace CoreWcf.Samples.Http
{
public class Program
{
public const int HTTP_PORT = 8088;
public const int HTTPS_PORT = 8443;
static void Main(string[] args)
{
IWebHost host = CreateWebHostBuilder(args).Build();
host.Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel(options =>
{
options.ListenLocalhost(HTTP_PORT);
options.ListenLocalhost(HTTPS_PORT, listenOptions =>
{
listenOptions.UseHttps();
if (Debugger.IsAttached)
{
listenOptions.UseConnectionLogging();
}
});
})
.UseStartup<BasicHttpBindingStartup>();
}
}
Run Code Online (Sandbox Code Playgroud)
启动.cs
using CoreWCF;
using CoreWCF.Configuration;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace CoreWcf.Samples.Http
{
public class BasicHttpBindingStartup
{
public void ConfigureServices(IServiceCollection services)
{
//Enable CoreWCF Services, with metadata (WSDL) support
services.AddServiceModelServices()
.AddServiceModelMetadata();
}
public void Configure(IApplicationBuilder app)
{
var wsHttpBindingWithCredential = new BasicHttpBinding(CoreWCF.Channels.BasicHttpSecurityMode.TransportWithMessageCredential);
wsHttpBindingWithCredential.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
app.UseServiceModel(builder =>
{
// Add the Demo Service
builder.AddService<DemoService>(serviceOptions =>
{
// Set a base address for all bindings to the service, and WSDL discovery
serviceOptions.BaseAddresses.Add(new Uri($"http://localhost:{Program.HTTP_PORT}/DemoService"));
serviceOptions.BaseAddresses.Add(new Uri($"https://localhost:{Program.HTTPS_PORT}/DemoService"));
})
// Add BasicHttpBinding endpoint
.AddServiceEndpoint<DemoService, IDemo>(wsHttpBindingWithCredential, "/wsHttpUserPassword", ep => { ep.Name = "AuthenticatedDemoEP"; });
builder.ConfigureServiceHostBase<DemoService>(CustomUserNamePasswordValidator.AddToHost);
// Configure WSDL to be available over http & https
var serviceMetadataBehavior = app.ApplicationServices.GetRequiredService<CoreWCF.Description.ServiceMetadataBehavior>();
serviceMetadataBehavior.HttpGetEnabled = serviceMetadataBehavior.HttpsGetEnabled = true;
});
}
}
}
Run Code Online (Sandbox Code Playgroud)
IDemo.cs(服务接口):
using CoreWCF;
namespace CoreWcf.Samples.Http
{
// Define a service contract.
[ServiceContract]
public interface IDemo
{
//[OperationContract(IsOneWay = true)]
[OperationContract]
string DemoRequest(string tagid, string readerid, string datetime);
}
}
Run Code Online (Sandbox Code Playgroud)
演示.cs(服务):
using CoreWCF.Channels;
using Microsoft.AspNetCore.Http;
using System.Net;
namespace CoreWcf.Samples.Http
{
public class DemoService : IDemo
{
public string DemoRequest(string tagid, string readerid, string datetime)
{
return $"Received tagid: {tagid}; readerid: {readerid}; datetime: {datetime}";
}
}
}
Run Code Online (Sandbox Code Playgroud)
CustomUserNamePasswordValidator.cs:
using CoreWCF;
using System.Threading.Tasks;
namespace CoreWcf.Samples.Http
{
internal class CustomUserNamePasswordValidator : CoreWCF.IdentityModel.Selectors.UserNamePasswordValidator
{
public override ValueTask ValidateAsync(string userName, string password)
{
bool valid = userName.ToLowerInvariant().EndsWith("valid")
&& password.ToLowerInvariant().EndsWith("valid");
if (!valid)
{
throw new FaultException("Unknown Username or Incorrect Password");
}
return new ValueTask();
}
public static void AddToHost(ServiceHostBase host)
{
var srvCredentials = new CoreWCF.Description.ServiceCredentials();
srvCredentials.UserNameAuthentication.UserNamePasswordValidationMode = CoreWCF.Security.UserNamePasswordValidationMode.Custom;
srvCredentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNamePasswordValidator();
host.Description.Behaviors.Add(srvCredentials);
}
}
}
Run Code Online (Sandbox Code Playgroud)
非常感谢您的帮助。干杯。
小智 5
CoreWCF 在 nuget 包 CoreWCF.WebHttp 中有它自己的WebOperationContext,您可以在那里设置传出 StatusCode,以便返回自定义状态代码,您可以这样做
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.YourDesiredStatusCode;
| 归档时间: |
|
| 查看次数: |
765 次 |
| 最近记录: |