RestSharp升级后枚举反序列化失败,求IRestSerializer自定义实现
RestSharp 110.2.0升级后枚举反序列化失败的解决方案
升级RestSharp从106.12.0到110.2.0后,出现枚举类型反序列化失败错误:
The JSON value could not be converted to SubExCore.Models.Enums.YearType. Path: $.body.YearType | LineNumber: 0 | BytePositionInLine:
The JSON value could not be converted to System.Nullable`1[SubExCore.Models.Enums.SectionType]. Path: $.body.sectionType | LineNumber: 0 | BytePositionInLine
问题根源
- 新版RestSharp废弃了旧的
RestSharp.Serializers.ISerializer接口,强制使用IRestSerializer - 默认序列化器切换为System.Text.Json,未沿用旧版本基于Newtonsoft.Json的自定义配置(字符串枚举转换、日期处理等)
- 原API代码中重复创建
RestRequest,导致自定义序列化器未被正确应用
解决方案
1. 自定义IRestSerializer实现(保留原Newtonsoft.Json配置)
以下实现完全兼容旧版本的序列化逻辑,同时适配新版RestSharp的接口要求:
using RestSharp; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System.IO; using System; public class CustomNewtonsoftSerializer : IRestSerializer { private readonly JsonSerializer _serializer; public CustomNewtonsoftSerializer() { var settings = new JsonSerializerSettings { Converters = { new StringEnumConverter(), // 字符串与枚举互转 new DateTimeJsonConverter() // 保留原自定义日期转换器 }, DateTimeZoneHandling = DateTimeZoneHandling.Utc, ContractResolver = new CamelCasePropertyNamesContractResolver() }; _serializer = JsonSerializer.Create(settings); } public string ContentType { get; set; } = "application/json"; public string Serialize(object obj) { using var stringWriter = new StringWriter(); using var jsonWriter = new JsonTextWriter(stringWriter); _serializer.Serialize(jsonWriter, obj); return stringWriter.ToString(); } public T Deserialize<T>(IRestResponse response) { using var stringReader = new StringReader(response.Content); using var jsonReader = new JsonTextReader(stringReader); return _serializer.Deserialize<T>(jsonReader); } public string Serialize(Parameter parameter) => Serialize(parameter.Value); public bool SupportsContentType(string contentType) { return contentType.Contains("json", StringComparison.OrdinalIgnoreCase); } }
2. 修正后的API调用代码
修复重复创建RestRequest的问题,确保自定义序列化器被正确绑定:
public YearBook GetYearBook() { // 仅创建一次RestRequest,避免覆盖配置 var request = new RestRequest(ApiPath, Method.Get) { Serializer = new CustomNewtonsoftSerializer() // 绑定自定义序列化器 }; var options = new RestClientOptions(BaseAddress) { CachePolicy = new System.Net.Http.Headers.CacheControlHeaderValue { NoCache = true, NoStore = true } }; using var client = new RestClient(options); if (!string.IsNullOrWhiteSpace(Token)) { client.AddDefaultHeader("Authorization", $"authToken {Token}"); } client.AddDefaultHeader("Cache-Control", "no-cache"); var response = client.Execute<YearBook>(request); return response.Data; }
额外注意事项
- 确保项目中保留
DateTimeJsonConverter类的实现(与旧版本一致) - 若JSON字段为蛇形命名(如
year_id),而模型属性为驼峰命名(如Year),需调整契约解析器为蛇形命名策略:
或在模型属性上添加ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() }[JsonProperty("year_id")]特性 - 新版RestSharp推荐使用异步方法
ExecuteAsync替代同步Execute,可根据项目需求调整
内容的提问来源于stack exchange,提问作者Hakuna Matata
相关产品推荐
相关产品推荐

