提问人:Hakuna Matata 提问时间:8/23/2023 最后编辑:Uwe KeimHakuna Matata 更新时间:9/20/2023 访问量:164
反序列化 RestClient 响应枚举转换错误 - 无法将 JSON 值转换为枚举
Deserialize RestClient response Enum Conversion Error - The JSON value could not be converted to Enum
问:
在我们的 asp.net 应用程序中,我们最近从 restsharp 106.12.0 升级到 110.2.0。 旧版本没有问题,但是在升级后对代码进行了很少的更改,我们收到了错误:
无法将 JSON 值转换为 SubExCore.Models.Enums.YearType. 路径:$.body。年份类型 |行号:0 |BytePositionInLine:
无法将 JSON 值转换为 System.Nullable'1[SubExCore.Models.Enums.SectionType]。路径: $.body.sectionType |行号:0 |BytePositionInLine
这是我通过反序列化 json 响应响应来获取 YearBook 响应的 api 方法。
public YearBook GetYearBook()
{
RestRequest request = new RestRequest(MethodType)
{
RequestFormat = DataFormat.Json,
Resource = ApiPath,
Method = Method.GET,
JsonSerializer = new CustomJsonSerializer()
};
RestRequest request = new RestRequest() { RequestFormat = DataFormat.Json, Resource = ApiPath, Method = Method.Get };
var options = new RestClientOptions()
{
BaseUrl = new Uri(BaseAddress),
CachePolicy = new System.Net.Http.Headers.CacheControlHeaderValue() { NoCache = true, NoStore = true }
};
RestClient client = new RestClient(options);
if (!Token.IsNullOrWhiteSpace())
{
client.AddDefaultHeader("Authorization", "authToken " + Token);
}
client.AddDefaultHeader("Cache-Control", "no-cache");
var myresonse = client.Execute<YearBook>(request);
return myresonse.Data;
}
这是我的 YearBook 类,带有 Enum 属性
[Table(TableName = "tblYearBook")]
public class YearBook
{
[Map(ColumnName = "year_id"), Key]
public int Year { get; set; }
[Map(ColumnName = "year_type")]
public YearType YearType { get; set; }
[Map(ColumnName = "section_type")]
public SectionType? Section { get; set; }
[Map(ColumnName = "college_name")]
public string CollegeName { get; set; }
[Map(ColumnName = "avg_pass")]
public decimal AvgPass { get; set; }
}
public enum YearType
{
FirstYear,
SecondYear,
ThirdYear
}
public enum SectionType
{
None,
MIT,
BIT
}
这是我从该方法获得的 json 响应。
{
"year_id": "2005",
"year_type": "FirstYear",
"section_type": "None",
"college_name": "St. Alphores Govt College",
"avg_pass" : 89
}
前面,我们已经在 RestSharp.Serializers.ISerializer 中实现了 CustomSerializer。新的 Restsharp 版本现在实现了 IRestSerializer 中的 customserializer。互联网上的 Restsharp 文档 neight 中没有足够的细节。 谁能给我一个正确的IRestSerializer实现,它具有以下序列化设置。
这是我现有的带有 Restsharp 版本 106.12.0 的自定义序列化程序类
public class CustomJsonSerializer : RestSharp.Serializers.ISerializer
{
public CustomJsonSerializer()
{
var restSerializer = new RestSharp.Serialization.Json.JsonSerializer();
this.ContentType = restSerializer.ContentType;
}
public string ContentType { get; set; }
public string DateFormat { get; set; }
public string Namespace { get; set; }
public string RootElement { get; set; }
private JsonSerializerSettings SerializerSettings
{
get
{
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new StringEnumConverter());
settings.Converters.Add(new DateTimeJsonConverter());
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
return settings;
}
}
string RestSharp.Serializers.ISerializer.Serialize(object obj)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(obj, SerializerSettings);
}
}
答:
还行。我简化了类,并使用提供的件为您创建了示例
void Main()
{
string j = "{\"year_id\":\"2005\",\"year_type\":\"FirstYear\",\"section_type\":\"None\",\"college_name\":\"St. Alphores Govt College\",\"avg_pass\":89}";
JsonConvert.DeserializeObject(j, SerializerSettings).Dump();
}
public class YearBook
{
[JsonProperty("year_id")]
public int Year { get; set; }
[JsonProperty("year_type")]
public YearType YearType { get; set; }
[JsonProperty("section_type")]
public SectionType? Section { get; set; }
[JsonProperty("college_name")]
public string CollegeName { get; set; }
[JsonProperty("avg_pass")]
public decimal AvgPass { get; set; }
}
public enum YearType
{
FirstYear,
SecondYear,
ThirdYear
}
public enum SectionType
{
None,
MIT,
BIT
}
private JsonSerializerSettings SerializerSettings
{
get
{
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new StringEnumConverter());
settings.Converters.Add(new DateTimeJsonConverter());
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
return settings;
}
}
class DateTimeJsonConverter : IsoDateTimeConverter
{
public DateTimeJsonConverter()
{
base.DateTimeFormat = "yyyy-MM-dd";
}
}
如您所见,字符串响应按预期反序列化为对象:
评论
Power Mouse 的答案告诉您如何配置 NewtonsoftJson 来处理问题的 JSON 和模型。
为了将它与 RestSharp 一起使用,您需要告诉它使用这些设置。
假设你有一个用于某个 API 客户端的类,它可能看起来像
class SomeApiClient {
readonly IRestClient _client;
public SomeApiClient() {
var settings = new JsonSerializerSettings();
settings.Converters.Add(new StringEnumConverter());
settings.Converters.Add(new DateTimeJsonConverter());
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
var options = new RestClientOptions { ... something here };
_client = new RestClient(
options,
configureSerialization: cfg => cfg.UseNewtonsoftJson(settings)
);
}
}
class DateTimeJsonConverter : IsoDateTimeConverter
{
public DateTimeJsonConverter()
{
base.DateTimeFormat = "yyyy-MM-dd";
}
}
文档中对此进行了描述,只需查看即可。
评论
JSON 值无法转换为 SubExCore.Models.Enums.YearType。路径:$.body。年份类型 |行号:0 |BytePositionInLine:
-- 此错误消息采用 System.Text.Json 生成的格式,而不是 Json.NET 格式。所以这是你实际使用的序列化程序。尝试申请,看看问题是否消失。[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter)]
public SectionType? Section { get; set; }
[Map(ColumnName = "year_id"), Key]
MapAttribute