System.Text.Json API 有类似 IContractResolver 的东西
Posted
技术标签:
【中文标题】System.Text.Json API 有类似 IContractResolver 的东西【英文标题】:System.Text.Json API is there something like IContractResolver 【发布时间】:2020-03-14 12:06:19 【问题描述】:在新的 System.Text.Json 中;命名空间是否有类似 IContractResolver 的东西我正在尝试将我的项目从 Newtonsoft 迁移出来。
这是我要迁移的课程之一:
public class SelectiveSerializer : DefaultContractResolver
private readonly string[] fields;
public SelectiveSerializer(string fields)
var fieldColl = fields.Split(',');
this.fields = fieldColl
.Select(f => f.ToLower().Trim())
.ToArray();
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
var property = base.CreateProperty(member, memberSerialization);
property.ShouldSerialize = o => fields.Contains(member.Name.ToLower());
return property;
【问题讨论】:
你用过.net core 3.0吗?能分享一下为什么要从Newtonsoft
迁移到System.Text.Json
吗?其实net core 3.0可以支持Newtonsoft
。你的代码是怎么做的工作吗?是用来小写正文数据的吗?
@Rena 此代码用于构建我们自己的 api 选择函数。例如: select=FirstName,Email,Id 序列化程序只会序列化指定的字段。类似于 odata 的做法,因为我们正在远离 odata
System.Text.Json
中的等效类型 -- JsonClassInfo
和 JsonPropertyInfo
-- 是 internal。有一个开放的增强功能Equivalent of DefaultContractResolver in System.Text.Json #42001 要求公开等效。
@dbc 很高兴知道:)
【参考方案1】:
System.Text.Json 中的等效类型——
JsonClassInfo
和JsonPropertyInfo
——是internal。有一个开放的增强 Equivalent of DefaultContractResolver in System.Text.Json #31257 要求公共等价物。 – dbc 11 月 25 日 19:11
Github 问题:
Open up metadata infrastructure of System.Text.Json #34456 Equivalent of DefaultContractResolver.CreateProperties override in System.Text.Json #60518 Equivalent of DefaultContractResolver in System.Text.Json #31257请试试这个: 我把它写成 System.Text.Json 的扩展来提供缺失的功能:https://github.com/dahomey-technologies/Dahomey.Json。
您会发现对编程对象映射的支持。
定义您自己的 IObjectMappingConvention 实现:
public class SelectiveSerializer : IObjectMappingConvention
private readonly IObjectMappingConvention defaultObjectMappingConvention = new DefaultObjectMappingConvention();
private readonly string[] fields;
public SelectiveSerializer(string fields)
var fieldColl = fields.Split(',');
this.fields = fieldColl
.Select(f => f.ToLower().Trim())
.ToArray();
public void Apply<T>(JsonSerializerOptions options, ObjectMapping<T> objectMapping) where T : class
defaultObjectMappingConvention.Apply<T>(options, objectMapping);
foreach (IMemberMapping memberMapping in objectMapping.MemberMappings)
if (memberMapping is MemberMapping<T> member)
member.SetShouldSerializeMethod(o => fields.Contains(member.MemberName.ToLower()));
定义你的类:
public class Employee
public int Id get; set;
public string FirstName get; set;
public string LastName get; set;
public string Email get; set;
通过调用命名空间 Dahomey.Json 中定义的扩展方法 SetupExtensions 的 JsonSerializerOptions 来设置 json 扩展:
JsonSerializerOptions options = new JsonSerializerOptions();
options.SetupExtensions();
为类注册新的对象映射约定:
options.GetObjectMappingConventionRegistry().RegisterConvention(
typeof(Employee), new SelectiveSerializer("FirstName,Email,Id"));
然后使用常规的 Sytem.Text.Json API 序列化您的类:
Employee employee = new Employee
Id = 12,
FirstName = "John",
LastName = "Doe",
Email = "john.doe@acme.com"
;
string json = JsonSerializer.Serialize(employee, options);
// "Id":12,"FirstName":"John","Email":"john.doe@acme.com";
【讨论】:
以上是关于System.Text.Json API 有类似 IContractResolver 的东西的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 System.Text.Json API 将流反序列化为对象
是否可以在 System.Text.Json 中找到未映射的属性?
System.Text.Json 中的 JsonExtensionData
为啥使用 System.Text.Json 的 JSON 反序列化这么慢?