在.NET Core 3中序列化Manatee.Json

编程入门 行业动态 更新时间:2024-10-28 00:26:59
本文介绍了在.NET Core 3中序列化Manatee.Json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

背景 我想从我的.NET Core 3应用程序中提供一些JsonSchema,以及序列化为JSON的其他对象.由于Manatee.Json经常更新并为JsonSchema提供良好的支持,因此它们是我的首选.同时,.NET Core 3为使用魔术返回对象(将对象转换为JSON文档)提供了出色的支持.

Background I want to provide some JsonSchema from my .NET Core 3 application, as well as other objects serialized into JSON. Since Manatee.Json is frequently updated and provides good support for JsonSchema, they are my preferred choice. At the same time, .NET Core 3 provides excellent support for returning objects with magic that transform them into JSON documents.

示例:

public ActionResult<MyFancyClass> MyFancyAction() { return new MyFancyClass { Property1 = "property 1 content", Property2 = "property 2 content", }; }

输出:

{ "Property1": "property 1 content", "Property2": "property 2 content" }

问题 .NET Core 3的System.Text.Json内部支持JSON,在上一个示例中使用了它.如果我尝试序列化Manatee.Json.Schema.JsonSchema,它的内部结构将被序列化,而不是json模式本身.

Problem .NET Core 3 has internal support for JSON with its System.Text.Json which is used in the previous example. If I try to serialize Manatee.Json.Schema.JsonSchema, its internal structure are serialized, not the json schema itself.

示例:

public ActionResult<MyFancyClass2> MyFancyAction2() { return new MyFancyClass2 { Property1 = "property 1 content", Property1Schema = new JsonSchema() .Type(JsonSchemaType.String) }; }

输出:

{ "Property1": "property 1 content", "Property1Schema": [{ "name":"type", "supportedVersions":15, "validationSequence":1, "vocabulary": { "id":"json-schema/draft/2019-09/vocab/validation", "metaSchemaId":"json-schema/draft/2019-09/meta/validation" } }] }

我希望这样:

{ "Property1": "property 1 content", "Property1Schema": { "type": "string", } }

Manatee.Json.JsonValue的内部结构也有冲突,其中System.Text.Json.JsonSerializer无法正确访问内部get方法,例如,我得到以下异常消息:

Manatee.Json.JsonValue also have a conflicting inner structure, where System.Text.Json.JsonSerializer fails to access internal get methods correctly and I get for instance this exception message:

Cannot access value of type Object as type Boolean.

发现 Manatee.Json.Schema.JsonSchema有一个.ToJson()方法,可用于获取作为JsonValue的正确json模式,但随后出现了我刚才提到的序列化Manatee.Json.JsonValue的问题.

Discovery Manatee.Json.Schema.JsonSchema has a .ToJson() method that can be used to get the correct json schema as a JsonValue, but then I get the problem I just mentioned with serializing Manatee.Json.JsonValue.

问题 有谁知道使System.Text.Json序列化Manatee.Json结构的方法吗?

Question Does anyone know a way to enable System.Text.Json to serialize Manatee.Json structures?

侧边标记 另一种前进的方式是完全替换System.Text.Json(请查看此问题).

Sidemark Another way forward is to replace System.Text.Json altogether (take a look at this question).

推荐答案

.NET Core 3 json序列化带有许多配置选项.其中之一是添加指定应如何序列化不同类型的转换器.前进的一种方法是为JsonSchema创建一个JsonConverter,为JsonValue创建另一个.

.NET Core 3 json serialization comes with a lot of configuration options. One of them is to add converters that specify how different types should be serialized. One way forward is to create a JsonConverter for JsonSchema and another for JsonValue.

对于JsonSchema,我们可以实现JsonSchemaConverter,当序列化/写入时,将json模式提取为JsonValue,然后要求序列化程序序列化该JsonValue.像这样:

For JsonSchema we can implement a JsonSchemaConverter that when serializing/writing, extracts the json schema as a JsonValue and ask the serializer to serialize that JsonValue instead. Like this:

public class JsonSchemaConverter : JsonConverter<JsonSchema> { public JsonSchemaConverter() { _manateeSerializer = new ManateeSerializer(); } private ManateeSerializer _manateeSerializer { get; set; } public override JsonSchema Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var jsonText = reader.GetString(); var jsonValue = JsonValue.Parse(jsonText); return _manateeSerializer.Deserialize<JsonSchema>(jsonValue); } public override void Write(Utf8JsonWriter writer, JsonSchema value, JsonSerializerOptions options) { var schemaAsJson = value.ToJson(_manateeSerializer); try { System.Text.Json.JsonSerializer.Serialize<JsonValue>(writer, schemaAsJson, options); } catch (Exception e) { Log.Information($"Failed to serialize JsonSchema ({e.Message});"); writer.WriteNullValue(); } } }

对于JsonValue,我们可以将其更改为System.Text.Json可以理解的内容,因为它毕竟是json.一种不幸的方法是将JsonValue序列化为string,并使用例如JsonDocument.Parse(string)对其进行解析并序列化其RootElement属性.感觉没有必要通过JsonDocument,因此,如果有人找到更好的解决方案,那就太好了! 可能的实现如下所示:

For JsonValue we can change it into something System.Text.Json understands, since it is json after all. One unfortunate approach is to serialize the JsonValue to a string, parsing it with for instance JsonDocument.Parse(string) and serialize its RootElement property. It feels so unnecessary to go via JsonDocument, so if anyone finds a better solution that would be great! A possible implementation can look like this:

public class JsonValueConverter : JsonConverter<JsonValue> { public override JsonValue Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var json = reader.GetString(); return JsonValue.Parse(json); } public override void Write(Utf8JsonWriter writer, JsonValue value, JsonSerializerOptions options) { string content = value.ToString(); try { var jsonDocument = JsonDocument.Parse(content); JsonSerializer.Serialize<JsonElement>(writer, jsonDocument.RootElement, options); } catch (Exception e) { Log.Warning($"JsonDocument.Parse(JsonValue) failed in JsonValueConverter.Write(,,).\n{e.Message}"); writer.WriteNullValue(); } } }

它们必须在Startup.cs处这样注册:

They must be registered at Startup.cs like this:

public void ConfigureServices(IServiceCollection services) { services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new JsonValueConverter()); options.JsonSerializerOptions.Converters.Add(new JsonSchemaConverter()); }); }

更多推荐

在.NET Core 3中序列化Manatee.Json

本文发布于:2023-11-13 23:27:21,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1585609.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:序列化   Core   NET   Manatee   Json

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!