【问题标题】:Can I intervene with System.Text.Json Serialization? [duplicate]我可以干预 System.Text.Json 序列化吗? [复制]
【发布时间】:2023-03-27 01:37:01
【问题描述】:

一般来说,我喜欢使用 .NET System.Text.Json JsonSerializerOptions.WriteIndented = true; 来获得具有良好可读性的 Json 输出。但是,对于只有一个属性的对象,我想覆盖序列化并使其不那么冗长。所以对于:

public class SimpleObj
{
    public string Text { get; set; }
}

而不是得到 :

{
  "text": "this is the value"
}

我想要:

{ "text": "this is the value" }

如果我使用JsonSerializerOptions.WriteIndented = false;,那么我的整个输出就不那么冗长了,但不是我想要的。 是否有某种扩展点或覆盖可以用来在本地为特定对象实现这一点?

【问题讨论】:

  • 是的,这是可能的,但您必须重新实现 Utf8JsonWriter,从 WriteNewLine 中删除代码或在调用时更改代码,请参阅完整源代码的链接并注意它是一个部分类在多个文件中。或者,您可以只在结果上 Replace(Environment.NewLine, "") 删除所有换行符
  • 您可以创建一个扩展方法或某种包装器,以根据属性的数量切换标志。通过反射可以很容易地找到属性的数量。
  • Json 是一种机器可读的序列化格式,也是人类可读的。你是在这里解决一个真正的问题,还是只是在没有必要时让事情看起来不错?
  • @Neil 好吧,我的用例需要一个非常紧凑但相当人类可读的输出。在我有几个单一属性对象的情况下,删除几个换行符可以提高可读性并减少空白。对于具有许多属性的对象,具有线喙和缩进非常适合文档和调试。

标签: c# json system.text.json


【解决方案1】:

我选择的解决方案是实现一个实现JsonConverter<SimpleObj> 的类,它允许我覆盖序列化期间调用的Read(...)Write(...) 方法。在Write() 中,我可以调用Utf8JsonWriter.WriteRawValue(),并使用SimpleObj.ToString() 覆盖作为参数,这正是我想要的。

public override void Write(Utf8JsonWriter writer, SimpleObj value, JsonSerializerOptions options)
{
  string ind = new String('\t', writer.CurrentDepth);
  writer.WriteRawValue(ind + value.ToString());
}
public class SimpleObj
{
  public string override ToString() => $"{{ \"text\": \"{text}\" }}";
}

【讨论】:

  • 如果 text 包含引号或 JSON 关心的其他特殊字符,这将无法正常工作。我建议不要自己尝试进行这种序列化,而是寻求知道如何正确进行序列化的类的帮助。
  • @LasseV.Karlsen 啊,很好。不是不可克服的,但毫无疑问它会在某些时候咬我。添加到单元测试 - 打勾。
猜你喜欢
  • 1970-01-01
  • 2023-04-07
  • 2012-01-19
  • 2018-06-21
  • 1970-01-01
  • 2022-01-02
  • 2021-07-17
相关资源
最近更新 更多