Jar*_*rru 10 c# json.net system.text.json asp.net-core-3.1
我正在将 ASP.NET Core 2 应用程序迁移到 ASP.NET Core 3。我的控制器需要返回具有已经是 JSON 字符串的属性的对象,因此它看起来像这样:
public class Thing {
public int Id { get; set; }
public string Name { get; set; }
public string Data { get; set; } // JSON Data
}
var thing = new Thing
{
Id = 1,
Name = "Thing",
Data = "{\"key\":\"value\"}"
};
Run Code Online (Sandbox Code Playgroud)
Thing应序列化,以便该Data属性不是字符串,而是 JSON 对象的一部分。像这样:
{
"id": 1,
"name": "Thing",
"data": {
"key": "value"
}
}
Run Code Online (Sandbox Code Playgroud)
在 .NET Core 2 中,Newtonsoft.Json我使用 的JRaw类型Data,因此序列化器知道该属性已经序列化为 JSON,并且不会尝试将其表示为字符串。
.NET Core 3 使用System.Text.Json,这与JRaw. 有没有等效的东西可以做同样的事情?我能够用作 的JsonElement类型Data并使用 转换字符串JsonDocument.Parse(jsonString).RootElement。这会产生所需的结果,但我想避免不必要的反序列化+序列化步骤,因为数据对象可能相对较大。
dbc*_*dbc 15
.NET 6 引入了Utf8JsonWriter.WriteRawValue(string json, bool skipInputValidation = false):
将输入写入 JSON 内容。预计输入内容是单个完整的 JSON 值。...
写入不受信任的 JSON 值时,请勿设置
skipInputValidation为true,因为这可能会导致写入无效的 JSON,或将无效的整体有效负载写入写入器实例。
因此,您现在可以引入以下转换器:
/// <summary>
/// Serializes the contents of a string value as raw JSON. The string is validated as being an RFC 8259-compliant JSON payload
/// </summary>
public class RawJsonConverter : JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using var doc = JsonDocument.ParseValue(ref reader);
return doc.RootElement.GetRawText();
}
protected virtual bool SkipInputValidation => false;
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) =>
// skipInputValidation : true will improve performance, but only do this if you are certain the value represents well-formed JSON!
writer.WriteRawValue(value, skipInputValidation : SkipInputValidation);
}
/// <summary>
/// Serializes the contents of a string value as raw JSON. The string is NOT validated as being an RFC 8259-compliant JSON payload
/// </summary>
public class UnsafeRawJsonConverter : RawJsonConverter
{
protected override bool SkipInputValidation => true;
}
Run Code Online (Sandbox Code Playgroud)
并将您选择的转换器应用到您的数据模型:
public class Thing {
public int Id { get; set; }
public string Name { get; set; }
[JsonConverter(typeof(UnsafeRawJsonConverter))]
public string Data { get; set; } // JSON Data
}
Run Code Online (Sandbox Code Playgroud)
笔记:
Utf8JsonReader似乎没有等效的方法来读取任何类型的原始值,因此JsonDocument仍然需要反序列化原始 JSON 值。
Utf8JsonWriter.WriteRawValue(null)并Utf8JsonWriter.WriteRawValue("null")生成相同的 JSON,即null. 反序列化时,doc.RootElement.GetRawText()似乎两者都返回 null 值,而不是包含 token 的字符串null。
您似乎关心性能,所以我应用UnsafeRawJsonConverter到您的数据模型。但是,只有在确定Data包含格式正确的 JSON 时才应使用此转换器。如果没有,请使用RawJsonConverter:
[JsonConverter(typeof(RawJsonConverter))]
public string Data { get; set; } // JSON Data
Run Code Online (Sandbox Code Playgroud)
在 .NET 5 及更早版本中WriteRawValue()不存在,因此您必须将传入的字符串解析为 aJsonDocument并写入:
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
using var doc = JsonDocument.Parse(value);
doc.WriteTo(writer);
}
Run Code Online (Sandbox Code Playgroud)
这当然会检查格式value是否良好;在早期版本中无法编写原始 JSON 并跳过输入验证。
演示小提琴在这里。
| 归档时间: |
|
| 查看次数: |
2884 次 |
| 最近记录: |