如何阻止Web API序列化模型并自主控制JSON序列化流程?
嘿,这个双重序列化的坑我之前也踩过!核心就是要切断Web API的自动序列化流程,把控制权完全握在自己手里。下面分两种主流Web API场景给你亲测有效的解决方案:
针对ASP.NET Web API(传统.NET Framework版本)
方案1:直接返回HttpResponseMessage,自己完成序列化
这种方式最直接,绕过Web API的默认序列化逻辑,手动把模型转成JSON字符串后塞进响应里:
public HttpResponseMessage GetMyModel() { var myModel = new MyModel { Id = 1, DisplayName = "示例数据" }; // 用Newtonsoft.Json(也就是Json.NET)执行自定义序列化 string customJson = JsonConvert.SerializeObject(myModel, new JsonSerializerSettings { // 这里加你的自定义逻辑:比如缩进格式化、忽略空值、自定义日期格式等 Formatting = Formatting.Indented, NullValueHandling = NullValueHandling.Ignore, DateFormatString = "yyyy-MM-dd" }); // 返回封装好的响应,指定内容类型为application/json return new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(customJson, Encoding.UTF8, "application/json") }; }
这样Web API只会把你生成的字符串原封不动返回,不会再做额外序列化。
方案2:全局替换默认JSON格式化器
如果想整个项目都用自定义序列化规则,可以替换掉默认的JsonMediaTypeFormatter:
// 先定义自己的格式化器 public class CustomJsonFormatter : JsonMediaTypeFormatter { public CustomJsonFormatter() { // 配置你的全局序列化规则 SerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), // 驼峰命名 ReferenceLoopHandling = ReferenceLoopHandling.Ignore, // 忽略循环引用 // 其他自定义配置... }; } } // 在WebApiConfig.cs的Register方法里注册 public static void Register(HttpConfiguration config) { // 清空默认格式化器 config.Formatters.Clear(); // 添加自定义格式化器 config.Formatters.Add(new CustomJsonFormatter()); }
之后Web API所有的模型序列化都会用你定义的规则,不用再手动处理每个接口。
针对ASP.NET Core Web API
方案1:返回ContentResult,手动控制序列化
Core里更推荐用IActionResult体系,直接返回序列化好的JSON字符串即可:
[HttpGet("mymodel")] public IActionResult GetMyModel() { var myModel = new MyModel { Id = 2, DisplayName = "Core示例" }; // 自定义序列化逻辑,这里用Newtonsoft.Json或者System.Text.Json都可以 string customJson = System.Text.Json.JsonSerializer.Serialize(myModel, new JsonSerializerOptions { WriteIndented = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); return Content(customJson, "application/json"); }
注意:如果返回的是已经序列化好的字符串,绝对不要用Ok(myModel)或者return myModel,否则Web API会把这个字符串再序列化一次,导致双重转义。
方案2:全局配置自定义序列化规则
如果想全局统一规则,在Program.cs里配置AddJsonOptions:
var builder = WebApplication.CreateBuilder(args); // 添加控制器并配置JSON序列化 builder.Services.AddControllers() .AddJsonOptions(options => { // 用System.Text.Json的自定义配置 options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); // 枚举转字符串 // 还可以添加自定义转换器、修改日期格式等 }); // 如果想改用Newtonsoft.Json代替默认的System.Text.Json,先安装NuGet包:Microsoft.AspNetCore.Mvc.NewtonsoftJson // builder.Services.AddControllers().AddNewtonsoftJson(options => // { // options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // // 其他Newtonsoft的配置... // }); var app = builder.Build(); // ...后续中间件配置
这样所有接口返回模型时,都会用你配置的规则序列化,避免双重序列化问题。
内容的提问来源于stack exchange,提问作者cool breeze
相关产品推荐
相关产品推荐

