自定义JsonConverter中JsonSerializer.Deserialize(ref reader)反序列化失败
问题分析与解决方案
问题根源
你的WeatherForecastData是只读结构体,且未为反序列化指定可用的构造函数。System.Text.Json默认要求结构体要么有无参构造函数,要么用[JsonConstructor]特性标记一个与JSON键匹配的带参构造函数。当前代码中,WeatherForecastData的构造函数要么接收string类型的Summary参数(与JSON中的int类型不匹配),要么未被序列化器识别,导致反序列化时只能生成默认值的结构体实例(所有字段为默认值,看起来像“空”)。
解决方案
方案一:标记适配反序列化的构造函数
给WeatherForecastData添加一个与JSON键严格匹配的带参构造函数,并标记[JsonConstructor]特性,让序列化器明确使用该构造函数创建实例:
internal readonly struct WeatherForecastData { public DateTime Date { get; } public int TC { get; } public int Summary { get; } // 用于反序列化的构造函数,参数名与JSON键一一对应 [JsonConstructor] public WeatherForecastData(DateTime Date, int TC, int Summary) { this.Date = Date; this.TC = TC; this.Summary = Summary; } // 保留用于序列化转换的原构造函数 public WeatherForecastData(DateTime date, int temperatureCelsius, string summary) { this.Date = date; this.TC = temperatureCelsius; this.Summary = summary == "Hot" ? 1 : summary == "Cold" ? -1 : 0; } }
方案二:手动读取Utf8JsonReader属性
如果不想修改WeatherForecastData,可以在Read方法中直接手动解析JSON的每个属性,跳过中间结构体的反序列化步骤:
public override WeatherForecast? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType != JsonTokenType.StartObject) { throw new JsonException("JSON格式错误,预期对象起始标记"); } DateTime date = default; int tempC = default; int summaryCode = default; while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { break; } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException("JSON格式错误,预期属性名"); } var propName = reader.GetString()!; reader.Read(); switch (propName) { case "Date": date = reader.GetDateTime(); break; case "TC": tempC = reader.GetInt32(); break; case "Summary": summaryCode = reader.GetInt32(); break; default: reader.Skip(); // 跳过未知属性,避免解析失败 break; } } return new WeatherForecast { Date = date, TemperatureCelsius = tempC, Summary = summaryCode == 1 ? "Hot" : summaryCode == -1 ? "Cold" : string.Empty }; }
验证修改
修改后重新运行TestDeserialize测试,即可正常反序列化出WeatherForecast实例。
内容的提问来源于stack exchange,提问作者CaseyHofland
相关产品推荐
相关产品推荐

