Mok*_*oki 5 c# json asp.net-core system.text.json .net-7.0
.NET7 包括对序列化器的许多改进System.Text.Json,其中之一是使用新[JsonPolymorphic]属性的类型的多态序列化。我正在尝试在我的 Asp.Net Web API 中使用它,但是尽管模型已正确设置,但它似乎并未序列化类型鉴别器。
仅当尝试通过网络发送对象时才会发生这种情况,当使用 JsonSerializer 时,一切似乎都运行良好。例如:
// This is my data model
[JsonPolymorphic]
[JsonDerivedType(typeof(SuccesfulResult), typeDiscriminator: "ok")]
[JsonDerivedType(typeof(ErrorResult), typeDiscriminator: "fail")]
public abstract record Result;
public record SuccesfulResult : Result;
public record ErrorResult(string Error) : Result;
Run Code Online (Sandbox Code Playgroud)
// Some test code that actually works
var testData = new Result[]
{
new SuccesfulResult(),
new ErrorResult("Whoops...")
};
var serialized = JsonSerializer.SerializeToDocument(testData);
// Serialized string looks like this:
// [{ "$type": "ok" }, { "$type": "fail", "error": "Whoops..." }]
// So type discriminators are in place and all is well
var deserialized = serialized.Deserialize<IEnumerable<Result>>()!;
// This assertion passes succesfully!
// We deserialized a collection polymorphically and didn't lose any type information.
testData.ShouldDeepEqual(deserialized);
Run Code Online (Sandbox Code Playgroud)
// However, when sending the object as a response in an API, the AspNet serializer
// seems to be ignoring the attributes:
[HttpGet("ok")]
public Result GetSuccesfulResult() => new SuccesfulResult();
[HttpGet("fail")]
public Result GetFailResult() => new ErrorResult("Whoops...");
Run Code Online (Sandbox Code Playgroud)
这些响应都没有使用类型鉴别器进行注释,并且我的强类型客户端无法将结果反序列化为正确的层次结构。
GET /api/ok HTTP/1.1
# =>
# ACTUAL: {}
# EXPECTED: { "$type": "ok" }
Run Code Online (Sandbox Code Playgroud)
GET /api/fail HTTP/1.1
# =>
# ACTUAL: { "error": "Whoops..." }
# EXPECTED: { "$type": "fail", "error": "Whoops..." }
Run Code Online (Sandbox Code Playgroud)
我是否缺少某种 API 配置,使控制器以多态方式序列化结果?
指定[JsonDerivedType(...)]各个子类和基本类型似乎可以解决问题,但似乎并不是故意的。这可能会在未来的版本中得到修复。
[JsonPolymorphic]
[JsonDerivedType(typeof(SuccesfulResult), typeDiscriminator: "ok")]
[JsonDerivedType(typeof(ErrorResult), typeDiscriminator: "fail")]
public abstract record Result;
[JsonDerivedType(typeof(SuccesfulResult), typeDiscriminator: "ok")]
public record SuccesfulResult : Result;
[JsonDerivedType(typeof(ErrorResult), typeDiscriminator: "fail")]
public record ErrorResult(string Error) : Result;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2850 次 |
| 最近记录: |