【发布时间】:2022-11-17 01:34:36
【问题描述】:
环境:.NET 6 WebAPI 应用程序
我有两个类,一个派生类,它们都可以用于将某个方法的输出序列化为 JSON 并将其发送给客户端。它们看起来像这样:
public class Base
{
public int? Prop1 { get; set; }
public string? Prop2 { get; set; }
public long? Prop3 { get; set; }
...
}
public class Derived: Base
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public new int? Prop1 { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public new string? Prop2 { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public new long? Prop3 { get; set; }
...
}
和一个具有 Base 对象集合的通用模型类:
public class Model
{
public List<Base>? Properties { get; set; }
...
}
我想始终序列化 Base 集合中的 Base 对象的键,但如果我正在序列化 Derived 对象的集合,则跳过值为 null 的键。我想要实现的示例代码:
var baseModel = new Model{ Properties = new List<Base>{ new Base { Prop1 = 1 } } };
var serialized = JsonSerializer.Serialize(baseModel);
// This returns '{ "properties": { "Prop1": 1, "Prop2": null, "Prop3": null }}'
var derivedModel = new Model { Properties = new List<Derived>{ new Derived { Prop1 = 1 }}};
// This doesn't compile because of type mismatch
var derivedModel2 = new Model { Properties = new List<Base>{ (Base)new Derived { Prop1 = 1 }}};
// This works, but also returns '{ "properties": { "Prop1": 1, "Prop2": null, "Prop3": null }}'
// I need to get '{ "properties": { "Prop1": 1 } }' here
关于在哪里看有什么建议吗?
UPD:我考虑过通用类的使用,但我的模型目前以下列方式使用(简化):
public class BusinessLogic: IBusinessLogic
{
... // Constructor with DI etc.
public async Task<Model> GetStuff(...)
{
...
var model = GetModelInternal(...);
...
return model;
}
}
public interface IBusinessLogic
{
...
public Task<Model> GetStuff(...);
...
}
public class MyController: ApiController
{
protected readonly IBusinessLogic _bl;
public MyController(..., IBusinessLogic bl)
{
_bl = bl;
}
[HttpGet]
public async Task<IActionResult> GetStuff(bool baseOrDerived, ...)
{
var model = await _bl.GetModel(baseOrDerived, ...);
return Json(model);
}
}
返回对象的类型(Base 或 Derived)需要取决于我从 API 客户端获取的输入参数 baseOrDerived。这意味着为了使用泛型,我需要通过控制器一直传递类型参数。此外,我将不得不向 IBusinessLogic/BusinessLogic 对引入相同的参数,而不是简单地从 DI 获取 IBusinessLogic 实例,我必须在那里获取一个 ServiceProvider 实例,在操作中创建一个范围并构造模板化IBusinessLogic 动态实例。鉴于这不是我想要这种行为的唯一课程,这对我来说似乎是一个真正的矫枉过正。
【问题讨论】:
-
我想我的道路是朝着自定义
ContractResolver的方向发展的。 -
是只需要序列化,还是还要反序列化?
-
@dbc 只序列化。我正在使用具有自己类的截然不同的模型来创建此类新对象。
标签: c# system.text.json