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

如何从字符串创建可序列化/反序列化的C# Version对象?

解决C# Version类型Newtonsoft.Json序列化反序列化的负字段问题

直接用自定义JsonConverter来处理Version类型的序列化和反序列化是最优雅的方案,完美适配各种版本字符串格式,同时彻底避免负字段导致的反序列化错误。

方案一:将Version序列化为版本字符串(推荐)

这种方式序列化后的JSON是简洁的版本字符串(比如"6.10.7011"),反序列化时直接解析字符串重建Version对象,完全绕开负字段问题。

自定义转换器代码

public class VersionConverter : JsonConverter<Version>
{
    public override void WriteJson(JsonWriter writer, Version value, JsonSerializer serializer)
    {
        // 利用Version.ToString()自动忽略值为-1的部分,输出标准版本字符串
        writer.WriteValue(value.ToString());
    }

    public override Version ReadJson(JsonReader reader, Type objectType, Version existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        if (reader.Value is string versionStr)
        {
            return Version.Parse(versionStr);
        }
        throw new JsonSerializationException("无法解析无效的版本字符串");
    }
}

使用方式

方式1:给属性添加特性标记

public class YourModel
{
    [JsonConverter(typeof(VersionConverter))]
    public Version ProtocolVersion { get; set; }
}

方式2:全局配置转换器

var jsonSettings = new JsonSerializerSettings();
jsonSettings.Converters.Add(new VersionConverter());

// 序列化
var json = JsonConvert.SerializeObject(yourModelInstance, jsonSettings);

// 反序列化
var model = JsonConvert.DeserializeObject<YourModel>(json, jsonSettings);

方案二:序列化时过滤负数值属性

如果希望序列化后仍是对象格式(而非字符串),可以通过自定义ContractResolver过滤掉值为-1的Build和Revision字段:

自定义ContractResolver代码

public class VersionContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
        
        // 过滤值为-1的Build字段
        if (member.DeclaringType == typeof(Version) && property.PropertyName == nameof(Version.Build))
        {
            property.ShouldSerialize = instance => ((Version)instance).Build >= 0;
        }
        
        // 过滤值为-1的Revision字段
        if (member.DeclaringType == typeof(Version) && property.PropertyName == nameof(Version.Revision))
        {
            property.ShouldSerialize = instance => ((Version)instance).Revision >= 0;
        }
        
        return property;
    }
}

使用方式

var jsonSettings = new JsonSerializerSettings();
jsonSettings.ContractResolver = new VersionContractResolver();

// 序列化后的JSON只会包含非-1的属性,比如Version("6.10.7011")会序列化为{"Major":6,"Minor":10,"Build":7011}
var json = JsonConvert.SerializeObject(yourModelInstance, jsonSettings);

两种方案都能解决你的问题,方案一更简洁直观,也更符合版本号的常规表示形式;方案二则保留了对象结构,适合需要结构化版本信息的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 10:44:54