使用JsonConvert反序列化时如何将第三方接口的字符串"1"/"0"转为布尔属性
报错原因
你编写的属性setter转换逻辑没有机会执行。Json.NET反序列化时会优先匹配JSON值类型与目标属性类型,默认不支持将字符串格式的"0"/"1"自动转换为布尔类型,在类型校验阶段就会抛出异常,不会进入你自定义的setter逻辑。
解决方案
方案1:使用自定义JsonConverter(推荐,通用性强)
首先实现自定义布尔类型转换器,专门处理字符串"1"/"0"到布尔值的转换逻辑:
using Newtonsoft.Json; public class StringToBooleanConverter : JsonConverter<bool> { public override bool ReadJson(JsonReader reader, Type objectType, bool existingValue, bool hasExistingValue, JsonSerializer serializer) { // 兼容原生布尔类型返回值 if (reader.Value is bool boolVal) { return boolVal; } var value = reader.Value?.ToString()?.Trim(); return value == "1"; } public override void WriteJson(JsonWriter writer, bool value, JsonSerializer serializer) { // 序列化时也输出"1"/"0"格式,和接口规范对齐,不需要可以删除 writer.WriteValue(value ? "1" : "0"); } }
然后给EmailDelivery属性添加转换器特性即可:
[JsonConverter(typeof(StringToBooleanConverter))] public bool EmailDelivery { get; set; }
如果项目中存在多个需要相同转换逻辑的布尔字段,也可以直接将转换器全局注册到你的序列化配置中,不需要给每个属性单独加特性:
public static class JsonSnakeCaseNameStrategySettings { public static JsonSerializerSettings Settings() { var settings = new JsonSerializerSettings { // 保留你原有的蛇形命名配置 ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() } }; // 全局注册自定义布尔转换器 settings.Converters.Add(new StringToBooleanConverter()); return settings; } }
方案2:使用影子属性承接序列化值(无需额外编写转换器,适合少量字段)
通过JsonProperty标记私有字段承接JSON返回的字符串值,对外暴露的布尔属性标记为忽略序列化,自行实现转换逻辑即可:
public class UserRegistrationCustomFields { // 私有字段承接接口返回的email_delivery字符串值 [JsonProperty("email_delivery")] private string EmailDeliveryRaw { get; set; } public string DeliveryTime { get; set; } // 对外暴露的布尔属性,不参与序列化 [JsonIgnore] public bool EmailDelivery => EmailDeliveryRaw == "1"; public bool SmsDelivery { get; set; } public string PhoneNumber { get; set; } }
内容的提问来源于stack exchange,提问作者Chris Rockwell
相关产品推荐
相关产品推荐

