如何在用户传入含重复字段的JSON时强制抛出异常?
解决重复JSON字段强制抛异常的方案
默认情况下,ASP.NET Core的JSON序列化器会自动覆盖重复字段的值(取最后出现的那个),要实现遇到重复字段就抛异常,可根据你使用的JSON序列化库选择以下方案:
方案一:使用System.Text.Json(ASP.NET Core 3.0+默认)
在项目的Program.cs(或Startup.cs)中配置JSON序列化选项,禁用重复字段允许:
// Program.cs 示例 var builder = WebApplication.CreateBuilder(args); // 添加控制器并配置JSON选项 builder.Services.AddControllers() .AddJsonOptions(options => { // 遇到重复JSON字段时抛出异常 options.JsonSerializerOptions.AllowDuplicateNames = false; }); var app = builder.Build(); // 其他中间件配置... app.MapControllers(); app.Run();
配置后,当请求中包含重复字段时,System.Text.Json会直接抛出JsonException,你的全局异常处理(或Action中的catch块)可以捕获这个异常并返回合适的错误响应。
方案二:使用Newtonsoft.Json(Json.NET)
如果你的项目使用Newtonsoft.Json替代默认序列化器,在配置中设置重复字段处理为错误:
// Program.cs 示例 var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers() .AddNewtonsoftJson(options => { // 遇到重复JSON字段时抛出异常 options.SerializerSettings.DuplicatePropertyNameHandling = DuplicatePropertyNameHandling.Error; }); var app = builder.Build(); // 其他中间件配置... app.MapControllers(); app.Run();
此配置会让Newtonsoft.Json在解析重复字段时抛出JsonSerializationException,同样可以被你的异常处理逻辑捕获。
补充:手动验证(可选)
如果需要更细粒度的控制,也可以在Action中读取原始请求内容,手动解析并检查重复字段:
修改你的EditUser Action:
[HttpPut] public async Task<ActionResult> EditUser([FromQuery(Name = "adminUserId")] Guid adminUserId) { StringValues clientConnectionString; try { // 读取原始JSON字符串 var rawJson = await Request.ReadAsStringAsync(); // 使用JObject解析并检查重复字段 var jObject = JObject.Parse(rawJson); // 检查是否有重复键 var propertyNames = jObject.Properties().Select(p => p.Name); if (propertyNames.GroupBy(n => n).Any(g => g.Count() > 1)) { return BadRequest(new ErrorResponseDTO() { MessageCode = "Invalid_Request_Duplicate_Fields", ErrorType = "Bad Request", RequestId = HttpContext.TraceIdentifier.ToString() }); } // 解析为UserDTO var userInfo = JsonConvert.DeserializeObject<UserDTO>(rawJson); // 后续业务逻辑... _userDA = new UserDA(); var result = _userDA.EditUser(userInfo, adminUserId, clientConnectionString); if (result.ReturnValue == -1) { return BadRequest(new ErrorResponseDTO() { MessageCode = _messageCodePrefix + result.Result, ErrorType = "Bad Request", RequestId = HttpContext.TraceIdentifier.ToString() }); } else { return Ok(new StatusInfoDTO() { MessageCode = _messageCodePrefix + result.Result, RequestId = HttpContext.TraceIdentifier.ToString(), ReturnValue = result.ReturnValue, Status = "Success" }); } } catch (JsonSerializationException ex) { // 捕获重复字段导致的序列化异常 _logger.LogCritical(ex.ToString()); return BadRequest(new ErrorResponseDTO() { MessageCode = "Invalid_Request_Duplicate_Fields", RequestId = HttpContext.TraceIdentifier.ToString(), ErrorType = "Bad Request" }); } catch (Exception ex) { _logger.LogCritical(ex.ToString()); return StatusCode(500, new ErrorResponseDTO() { MessageCode = "Internal server error", RequestId = HttpContext.TraceIdentifier.ToString(), ErrorType = "Server Error" }); } }
注意:这种方式需要你手动处理JSON解析,不如全局配置高效,但适合需要自定义错误信息的场景。
内容的提问来源于stack exchange,提问作者Bhumika
相关产品推荐
相关产品推荐

