【问题标题】:System.Text.Json Serialize null strings into empty strings globallySystem.Text.Json 将空字符串全局序列化为空字符串
【发布时间】:2021-04-27 23:48:38
【问题描述】:

将代码从 newtonsoft json 迁移到 system.text.json 时

我需要将所有可为空的字符串呈现为空字符串。

我写了以下转换器,但所有空字符串值仍然呈现为空。

对于空字符串值,不会调用 Write 方法。断点永远不会被击中。

public class EmptyStringConverter : JsonConverter<string>
{
    public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        => Convert.ToString(reader.GetString(), CultureInfo.CurrentCulture);

    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        if (writer == null)
            throw new ArgumentNullException(nameof(writer));
        writer.WriteStringValue(value ?? "");
    }
}

启动代码

services.AddControllers()
    .AddJsonOptions(option =>
    {
        option.JsonSerializerOptions.Converters.Add(new EmptyStringConverter());
    });

控制台示例

class Program
{
    static void Main(string[] args)
    {
        var jsonSerializerOptions = new JsonSerializerOptions();
        jsonSerializerOptions.Converters.Add(new EmptyStringConverter());
        var json = JsonSerializer.Serialize(new Model() { FirstName = null }, jsonSerializerOptions);
    }
}

public class EmptyStringConverter : JsonConverter<string>
{
    public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        => Convert.ToString(reader.GetString(), CultureInfo.CurrentCulture);

    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        if (writer == null)
            throw new ArgumentNullException(nameof(writer));
        writer.WriteStringValue(value ?? "");
    }
}

public class Model
{
    public string FirstName { get; set; }
}

【问题讨论】:

标签: c# .net-core system.text.json


【解决方案1】:

在 .NET 5.0 中,这可以通过覆盖 JsonConverter&lt;T&gt;.HandleNull 并返回 true 来完成:

public class EmptyStringConverter : JsonConverter<string>
{
    public override bool HandleNull => true;
    
    public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        => reader.TokenType == JsonTokenType.Null ? "" : reader.GetString();

    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) =>
        writer.WriteStringValue(value ?? "");
}

更多信息,请参阅Handle null values

演示小提琴here.

在 .NET Core 3.x 中未实现。来自 .NET Core 3.x 中的 Handle null values

处理空值

默认情况下,序列化器处理空值如下:

  • 对于引用类型和Nullable&lt;T&gt; 类型:

    • 它不会在序列化时将 null 传递给自定义转换器。
    • 它不会在反序列化时将 JsonTokenType.Null 传递给自定义转换器。
    • 它在反序列化时返回一个空实例。
    • 它在序列化时直接用 writer 写入 null。
  • 对于不可为空的值类型:

    • 它在反序列化时将 JsonTokenType.Null 传递给自定义转换器。 (如果没有可用的自定义转换器,则该类型的内部转换器会抛出 JsonException 异常。)

这种空值处理行为主要是通过跳过对转换器的额外调用来优化性能。此外,它避免了强制可空类型的转换器在每个 Read 和 Write 方法覆盖开始时检查 null。

【讨论】:

    【解决方案2】:

    试试看

    /// <summary>
    /// Convert empty to null when read data json
    /// </summary>
    public class EmptyStringToNullConverter : JsonConverter<string>
    {
        /// <summary>
        /// Override CanConvert method of JsonConverter
        /// This instance only convert the string type.
        /// </summary>
        /// <returns></returns>
        public override bool CanConvert(Type typeToConvert)
        {
            return typeToConvert == typeof(string);
        }
    
        /// <summary>
        /// Override ReadJson method of JsonConverter
        /// Convert string null to empty
        /// </summary>
        /// <returns></returns>
        public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            string value = (string)reader.GetString();
            return value ?? String.Empty;
        }
    
        /// <summary>
        /// Override WriteJson method of JsonConverter
        /// </summary>
        public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
        {
            throw new NotImplementedException("Unnecessary");
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多