簡體   English   中英

System.Text.Json 將空字符串全局序列化為空字符串

[英]System.Text.Json Serialize null strings into empty strings globally

將代碼從 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; }
}

在 .NET 5.0 中,這可以通過覆蓋JsonConverter<T>.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 ?? "");
}

有關更多信息,請參閱處理空值

演示小提琴在這里

在 .NET Core 3.x中沒有實現。 從 .NET Core 3.x 中的處理空值開始:

處理空值

默認情況下,序列化程序按如下方式處理空值:

  • 對於引用類型和Nullable<T>類型:

    • 它不會在序列化時將 null 傳遞給自定義轉換器。
    • 它不會在反序列化時將 JsonTokenType.Null 傳遞給自定義轉換器。
    • 它在反序列化時返回一個空實例。
    • 它在序列化時直接向作者寫入 null。
  • 對於不可為空的值類型:

    • 它在反序列化時將 JsonTokenType.Null 傳遞給自定義轉換器。 (如果沒有可用的自定義轉換器,則該類型的內部轉換器會拋出 JsonException 異常。)

這種空處理行為主要是通過跳過對轉換器的額外調用來優化性能。 此外,它避免強制可空類型的轉換器在每次讀取和寫入方法覆蓋開始時檢查空值。

嘗試一下

/// <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");
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM