You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将自定义TaxpayerIdentificationNumber结构体序列化为字符串并支持反序列化?

自定义结构体的字符串序列化与反序列化实现

针对你的需求,不需要用ISerializable(它主要适配.NET二进制序列化场景),主流JSON序列化库都支持通过自定义转换器实现类似DateTime的特殊序列化逻辑,以下分两种常用库给出具体实现:

方案一:System.Text.Json(.NET Core/.NET 5+ 默认库)

结构体与转换器实现

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

public struct TaxpayerIdentificationNumber
{
    private readonly long _number;

    public TaxpayerIdentificationNumber(long number)
    {
        // 可添加13位数字校验逻辑
        if (number.ToString().Length != 13)
            throw new ArgumentException("税号必须为13位数字", nameof(number));
        _number = number;
    }

    // 提供内部字段的访问入口,供转换器使用
    public long GetNumber() => _number;
}

public class TinJsonConverter : JsonConverter<TaxpayerIdentificationNumber>
{
    // 序列化:将结构体转为纯数字字符串
    public override void Write(Utf8JsonWriter writer, TaxpayerIdentificationNumber value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.GetNumber().ToString());
    }

    // 反序列化:从字符串还原为结构体
    public override TaxpayerIdentificationNumber Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType != JsonTokenType.String)
            throw new JsonException("税号必须是字符串格式");
        
        if (!long.TryParse(reader.GetString(), out long number))
            throw new JsonException("无效的税号数字格式");

        return new TaxpayerIdentificationNumber(number);
    }
}

使用示例

// 初始化结构体
var tin = new TaxpayerIdentificationNumber(1234567890123);

// 配置序列化选项
var options = new JsonSerializerOptions();
options.Converters.Add(new TinJsonConverter());

// 序列化结果为 "1234567890123"
string serialized = JsonSerializer.Serialize(tin, options);

// 反序列化
var deserializedTin = JsonSerializer.Deserialize<TaxpayerIdentificationNumber>(serialized, options);

方案二:Newtonsoft.Json(Json.NET)

结构体与转换器实现

using System;
using Newtonsoft.Json;

public struct TaxpayerIdentificationNumber
{
    private readonly long _number;

    public TaxpayerIdentificationNumber(long number)
    {
        if (number.ToString().Length != 13)
            throw new ArgumentException("税号必须为13位数字", nameof(number));
        _number = number;
    }

    public long GetNumber() => _number;
}

public class TinJsonConverter : JsonConverter<TaxpayerIdentificationNumber>
{
    public override void WriteJson(JsonWriter writer, TaxpayerIdentificationNumber value, JsonSerializer serializer)
    {
        writer.WriteValue(value.GetNumber().ToString());
    }

    public override TaxpayerIdentificationNumber ReadJson(JsonReader reader, Type objectType, TaxpayerIdentificationNumber existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        if (reader.Value is not string tinStr)
            throw new JsonException("税号必须是字符串格式");
        
        if (!long.TryParse(tinStr, out long number))
            throw new JsonException("无效的税号数字格式");

        return new TaxpayerIdentificationNumber(number);
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(TaxpayerIdentificationNumber);
    }
}

使用示例

可以通过特性直接标记结构体,无需手动配置选项:

[JsonConverter(typeof(TinJsonConverter))]
public struct TaxpayerIdentificationNumber { /* 结构体代码 */ }

// 序列化
var tin = new TaxpayerIdentificationNumber(1234567890123);
string serialized = JsonConvert.SerializeObject(tin); // 结果为 "1234567890123"

// 反序列化
var deserializedTin = JsonConvert.DeserializeObject<TaxpayerIdentificationNumber>(serialized);

补充说明

DateTime的特殊序列化逻辑,本质也是序列化库内置了对应的转换器,上述自定义转换器的思路和它完全一致,能让你的结构体实现相同的"纯字符串"序列化效果。

内容的提问来源于stack exchange,提问作者Destall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 13:18:02