C#反序列化含NuGetVersion的类报错,求解决方案
问题根源
System.Text.Json的反序列化逻辑是先创建对象实例,再为属性赋值。哪怕NuGetVersion有{get;set;}属性,反序列化第一步需要实例化这个类型时,它没有符合要求的构造函数:
- 无无参构造函数
- 无单个参数的构造函数(无法通过单一值直接实例化)
- 所有参数化构造函数都未标记
[JsonConstructor]
因此反序列化器无法创建NuGetVersion实例,直接抛出NotSupportedException。
解决办法
方法1:自定义JsonConverter<NuGetVersion>(推荐)
创建转换器,告知System.Text.Json如何在字符串与NuGetVersion之间转换:
public class NuGetVersionConverter : JsonConverter<NuGetVersion> { public override NuGetVersion Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { string versionString = reader.GetString()!; return NuGetVersion.Parse(versionString); } public override void Write(Utf8JsonWriter writer, NuGetVersion value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString()); } }
使用方式有两种:
- 反序列化时传入转换器配置:
var options = new JsonSerializerOptions(); options.Converters.Add(new NuGetVersionConverter()); Nuget? deserializedObject = JsonSerializer.Deserialize<Nuget>(DirectoryManager.ReadResourceFromExternal(filePath), options); - 直接在
Nuget类的属性上标记转换器:public class Nuget { public string? Name { get; set; } public string? Id { get; set; } [JsonConverter(typeof(NuGetVersionConverter))] public NuGetVersion Version { get; set; } public string? PackageSource { get; set; } public System.DateTimeOffset BlobCreation { get; set; } }
方法2:用字符串替代NuGetVersion再手动转换
这是你考虑的方案,完全可行。修改Nuget类,通过字符串字段完成序列化,再通过属性封装转换逻辑:
public class Nuget { public string? Name { get; set; } public string? Id { get; set; } // 用于序列化/反序列化的字符串版本 public string? VersionString { get; set; } // 业务逻辑用的NuGetVersion,忽略序列化 [JsonIgnore] public NuGetVersion? Version { get => VersionString != null ? NuGetVersion.Parse(VersionString) : null; set => VersionString = value?.ToString(); } public string? PackageSource { get; set; } public System.DateTimeOffset BlobCreation { get; set; } }
方法3:切换到Newtonsoft.Json(备选)
Newtonsoft.Json默认支持通过类型的Parse方法完成反序列化,无需额外配置,直接替换序列化逻辑即可:
using Newtonsoft.Json; Nuget? deserializedObject = JsonConvert.DeserializeObject<Nuget>(DirectoryManager.ReadResourceFromExternal(filePath));
内容的提问来源于stack exchange,提问作者Vincze Szilárd
相关产品推荐
相关产品推荐

