c# - C# asp.net core中现有类的JSON自定义序列化和反序列化
问题描述
我有现有的第三方 DLL - 它有几个类。我没有这个 DLL 的源代码。让我们假设它具有如下定义的 Book 类
public class Book{
public String Id { get; set; }
public String Title { get; set; }
public String Author{ get; set; }
public List<Page> Pages { get; set; }
}
我已经创建了 Asp.net Core Web API 项目并引用了 DLL 并为 http 的 GET 方法编写了 API 控制器。
[HttpGet("{id}")]
public ActionResult<Book> Get(string id)
{
Book b = Book.FindById(id); // This utility function returns Book instance.
return Ok(b);
}
我的要求是 JSON 的返回值应该类似于
{
"id" : "1234",
"Title" : "How to Custom Serialize JSON",
"Author" : "Myself",
"NumberOfPages" : 100
}
所以基本上,每当发生 JSON 序列化时,我想确保 Pages 属性没有被序列化,因为它有很多复杂性。但我应该能够添加新属性NumberOfPages。基本上我想控制序列化。我见过很多例子,但我找不到这个我想自定义序列化现有类的特殊情况。
我现在不担心反序列化。
我可以看到序列化从
Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter.WriteObject(TextWriter writer, Object value)
谢谢, 阿图尔
解决方案
为了获得适用于全球的解决方案:
- 创建自定义转换器
- 注册该转换器
创建转换器
最简单的方法:创建一个派生自JsonConverter的类:
public class BookConverter : JsonConverter<Book>
{
public override void WriteJson(JsonWriter writer, Book value, JsonSerializer serializer)
{
var bookObject = (JObject)JToken.FromObject(value);
bookObject.Remove(nameof(value.Pages));
bookObject.Add(new JProperty("NumberOfPages", value.Pages.Count));
bookObject.WriteTo(writer);
}
public override Book ReadJson(JsonReader reader, Type objectType, Book existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return new Book(); //TODO: fix me, now it is enough to make it compile
}
}
- 在这里,我将
Book
实例 (value
) 转换为JObject
. - 我
Pages
通过调用Remove
. - 我
NumberOfPages
通过调用扩展了输出Add
。 - 我跳过了这一
ReadJson
部分,因为它超出了这个问题的范围。
寄存器转换器
.NET 核心 2.x
public void ConfigureServices(IServiceCollection services)
{
services
.AddControllers()
.AddJsonOptions(opts =>
{
opts.SerializerSettings.Converters.Add(new BookConverter());
});
}
.NET Core 3.x 或 .NET 5.x
对于 ASP.NET Core 3.1 或更高版本,默认的 json 序列化程序是System.Text.Json
. 为了使用 Json.Net,您需要安装Microsoft.AspNetCore.Mvc.NewtonsoftJson包。这公开了一个方法AddNewtonsoftJson
,您可以在其中注册自定义转换器:
public void ConfigureServices(IServiceCollection services)
{
services
.AddControllers()
.AddNewtonsoftJson(opts =>
{
opts.SerializerSettings.Converters.Add(new BookConverter());
});
}
使用这种方法Book
,当 ASP.NET Core 调用序列化程序时,所有实例都将转换为所需的格式。
推荐阅读
- matlab - 我怎样才能摆脱 MATLAB 中的这个错误?
- delphi - Delphi BPL 无法动态加载 64 位包
- objective-c - 禁用按钮循环(NStimer 或 MouseMove)XCode Objective-C MacOS
- c - Zentyal 代理 6.1 的问题和嵌入式应用程序中的连接请求
- reactjs - 修复从一页转移到另一页时的高度偏移
- discord.py - 在 *any* 事件 discord.py
- php - datetimepicker 仅适用于以多更新形式选择的上一行上方的行
- heroku - 是否仍然可以让 cloudflare dns 指向免费的 heroku 实例?
- yaml - 访问某些页面时 tooling_sidebar.yml 崩溃
- javascript - 使用 Hooks 从函数中响应 Native Post 调用