C# JSON字串容錯轉換類別設計與驗證

C# JSON字串容錯轉換類別設計與驗證

C# JSON字串容錯轉換類別設計與驗證


資料來源: gemini3 免費版


C#線上編譯: https://dotnetfiddle.net/                    [.net10]


會動程式碼:

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

// 1. 處理 int? 的轉換器
public class FlexibleIntConverter : JsonConverter<int?>
{
    public override int? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.Number) return reader.GetInt32();
        if (reader.TokenType == JsonTokenType.String)
        {
            string value = reader.GetString();
            if (string.IsNullOrWhiteSpace(value)) return null;
            if (int.TryParse(value, out int result)) return result;
        }
        if (reader.TokenType == JsonTokenType.Null) return null;
        
        return null;
    }

    public override void Write(Utf8JsonWriter writer, int? value, JsonSerializerOptions options)
    {
        if (value.HasValue) writer.WriteNumberValue(value.Value);
        else writer.WriteNullValue();
    }
}

// 2. 處理 string 的轉換器
public class FlexibleStringConverter : JsonConverter<string>
{
    public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 處理數字:將其視為原始文字直接讀取成字串
        if (reader.TokenType == JsonTokenType.Number)
        {
            // 使用 GetRawValue().ToArray() 並轉為字串,避免損壞 reader 狀態
            return System.Text.Encoding.UTF8.GetString(reader.ValueSpan);
        }

        if (reader.TokenType == JsonTokenType.String)
            return reader.GetString();

        if (reader.TokenType == JsonTokenType.Null)
            return null;

        //  fallback: 嘗試獲取原始文字
        return null;
    }

    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value);
    }
}

// 3. 資料模型
public class OrderConfig
{
    [JsonConverter(typeof(FlexibleIntConverter))]
    public int? def_order_type { get; set; }

    [JsonConverter(typeof(FlexibleIntConverter))]
    public int? def_unit_sid { get; set; }

    [JsonConverter(typeof(FlexibleStringConverter))]
    public string? def_tax_sid { get; set; }

    [JsonConverter(typeof(FlexibleStringConverter))]
    public string? pos_check_in_mode { get; set; }
}

public class Program
{
    public static void Main()
    {
        string json1 = "{\"def_order_type\": 10, \"def_unit_sid\": 40, \"def_tax_sid\": 12345}"; 
        string json2 = "{\"def_order_type\": \"207\", \"def_unit_sid\": \"\"}"; 
        string json3 = "{}"; 

        PrintResult("情境 1 (純數字與數字轉字串)", json1);
        PrintResult("情境 2 (字串與空字串)", json2);
        PrintResult("情境 3 (空物件)", json3);
    }

    static void PrintResult(string title, string json)
    {
        var obj = JsonSerializer.Deserialize<OrderConfig>(json);

        Console.WriteLine($"=== {title} ===");
        Console.WriteLine($"Order Type: {obj.def_order_type?.ToString() ?? "null"} ({obj.def_order_type?.GetType().Name ?? "Null"})");
        Console.WriteLine($"Unit SID: {obj.def_unit_sid?.ToString() ?? "null"} ({obj.def_unit_sid?.GetType().Name ?? "Null"})");
        Console.WriteLine($"Tax SID: {obj.def_tax_sid ?? "null"} ({obj.def_tax_sid?.GetType().Name ?? "Null"})");
        Console.WriteLine(new string('-', 30));
    }
}


執行結果:

=== 情境 1 (純數字與數字轉字串) ===
Order Type: 10 (Int32)
Unit SID: 40 (Int32)
Tax SID: 12345 (String)
------------------------------
=== 情境 2 (字串與空字串) ===
Order Type: 207 (Int32)
Unit SID: null (Null)
Tax SID: null (Null)
------------------------------
=== 情境 3 (空物件) ===
Order Type: null (Null)
Unit SID: null (Null)
Tax SID: null (Null)
------------------------------

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *