.NET Core API设置同状态自定义错误码及调用带Basic Auth的WCF服务问询
.NET Core API 相关问题解答
1. 相同响应状态下返回自定义错误码
实现思路
通过定义通用响应结构体,在响应体中独立添加自定义错误码字段,该字段和HTTP响应状态码解耦,即可实现相同HTTP状态码下返回不同的业务自定义错误码。可配合全局结果/异常过滤器实现统一封装,无需每个接口重复编写代码。
示例代码
// 1. 定义通用响应结构体 public class ApiResult<T> { /// <summary> /// 业务自定义错误码,0代表成功 /// </summary> public int Code { get; set; } /// <summary> /// 响应提示信息 /// </summary> public string Msg { get; set; } /// <summary> /// 响应数据 /// </summary> public T Data { get; set; } }
// 2. 控制器返回示例(同HTTP 400状态码,不同自定义错误码) [HttpPost("validate")] public IActionResult ValidateParam(int input) { if (input < 0) { return BadRequest(new ApiResult<object> { Code = 10001, Msg = "输入参数不能为负数", Data = null }); } if (input > 100) { return BadRequest(new ApiResult<object> { Code = 10002, Msg = "输入参数不能超过100", Data = null }); } return Ok(new ApiResult<int> { Code = 0, Msg = "校验通过", Data = input }); }
2. 调用带Basic Authentication的WCF服务(无硬编码凭证)
实现思路
- 将WCF服务地址、用户名、密码等配置存到
appsettings.json配置文件,运行时读取,避免硬编码; - 使用.NET Core的WCF Web Service Reference工具生成服务客户端;
- 依赖注入时读取配置初始化WCF客户端,注入Basic Auth凭证,支持两种凭证传递方式:直接设置客户端凭据、手动添加HTTP Authorization请求头。
示例代码
步骤1:添加配置
// appsettings.json { "WcfServiceConfig": { "ServiceUrl": "https://your-wcf-service-address/Service.svc", "UserName": "your_basic_auth_username", "Password": "your_basic_auth_password" } }
// 定义配置绑定类 public class WcfServiceConfig { public string ServiceUrl { get; set; } public string UserName { get; set; } public string Password { get; set; } }
步骤2:注册WCF客户端与配置
// Program.cs var builder = WebApplication.CreateBuilder(args); // 绑定WCF配置 builder.Services.Configure<WcfServiceConfig>(builder.Configuration.GetSection("WcfServiceConfig")); // 注册WCF服务客户端 builder.Services.AddScoped(provider => { var config = provider.GetRequiredService<IOptions<WcfServiceConfig>>().Value; // 根据WCF服务是HTTP/HTTPS选择安全模式:HTTP用BasicHttpSecurityMode.None,HTTPS用Transport var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport); var endpointAddress = new EndpointAddress(config.ServiceUrl); // 这里的YourWcfServiceClient是你添加服务引用后自动生成的客户端类 var client = new YourWcfServiceClient(binding, endpointAddress); // 方式1:直接设置客户端凭据(适用大部分标准Basic Auth WCF服务) client.ClientCredentials.UserName.UserName = config.UserName; client.ClientCredentials.UserName.Password = config.Password; // 方式2:如果方式1不生效,可通过自定义消息拦截器手动加请求头,取消注释下方代码即可 // client.Endpoint.EndpointBehaviors.Add(new BasicAuthEndpointBehavior(config.UserName, config.Password)); return client; });
步骤3:自定义消息拦截器(可选,仅当方式1不生效时使用)
using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; using System.Text; // 消息拦截器,添加Basic Auth请求头 public class BasicAuthMessageInspector : IClientMessageInspector { private readonly string _userName; private readonly string _password; public BasicAuthMessageInspector(string userName, string password) { _userName = userName; _password = password; } public object BeforeSendRequest(ref Message request, IClientChannel channel) { var authBytes = Encoding.UTF8.GetBytes($"{_userName}:{_password}"); var authHeaderValue = $"Basic {Convert.ToBase64String(authBytes)}"; var httpProperties = new HttpRequestMessageProperty(); httpProperties.Headers.Add("Authorization", authHeaderValue); request.Properties[HttpRequestMessageProperty.Name] = httpProperties; return null; } public void AfterReceiveReply(ref Message reply, object correlationState) { // 无需处理响应可留空 } } // 端点行为,注册拦截器 public class BasicAuthEndpointBehavior : IEndpointBehavior { private readonly string _userName; private readonly string _password; public BasicAuthEndpointBehavior(string userName, string password) { _userName = userName; _password = password; } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { clientRuntime.ClientMessageInspectors.Add(new BasicAuthMessageInspector(_userName, _password)); } public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) {} public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) {} public void Validate(ServiceEndpoint endpoint) {} }
步骤4:业务代码调用WCF服务
[ApiController] [Route("api/wcf")] public class WcfTestController : ControllerBase { private readonly YourWcfServiceClient _wcfClient; public WcfTestController(YourWcfServiceClient wcfClient) { _wcfClient = wcfClient; } [HttpGet("call")] public async Task<IActionResult> CallWcfService([FromQuery] int inputId) { // 调用WCF服务方法,inputId是你需要传递的整型参数 var response = await _wcfClient.YourTargetWcfMethodAsync(inputId); return Ok(response); } }
内容的提问来源于stack exchange,提问作者Overthehacks
相关产品推荐
相关产品推荐

