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) ------------------------------