每当我尝试反序列化下面的json字符串时,我都会收到此错误:
错误:
其他信息:转换值时出错 " invalid_request_error"输入' ErrorType'。路径'类型',第2行, 第33位。
Json字符串
{
"error": {
"type": "invalid_request_error",
"message": "Invalid request (check that your POST content type is application/x-www-form-urlencoded). If you have any questions, we can help at https://support.stripe.com/."
}
}
代码
private void btnDeserialize_Click(object sender, EventArgs e)
{
var r = Components.JsonMapper.MapFromJson<Components.DTO.Error>(txtToDeserialize.Text, "error");
txtDeserialized.Text = JsonConvert.SerializeObject(r);
}
JsonMapper
public static class JsonMapper
{
public static T MapFromJson<T>(string json, string parentToken = null)
{
var jsonToParse = string.IsNullOrEmpty(parentToken) ? json : JObject.Parse(json).SelectToken(parentToken).ToString();
return JsonConvert.DeserializeObject<T>(jsonToParse);
}
}
枚举
public enum ErrorCode
{
Default,
[JsonProperty("invalid_number")]
InvalidNumber,
[JsonProperty("invalid_expiry_month")]
InvalidExpiryMonth,
[JsonProperty("invalid_expiry_year")]
InvalidExpiryYear,
[JsonProperty("invalid_cvc")]
InvalidCvc,
[JsonProperty("incorrect_number")]
IncorrectNumber,
[JsonProperty("expired_card")]
ExpiredCard,
[JsonProperty("incorrect_cvc")]
IncorrectCvc,
[JsonProperty("incorrect_zip")]
IncorrectZip,
[JsonProperty("card_declined")]
CardDeclined,
[JsonProperty("missing")]
Missing,
[JsonProperty("processing_error")]
ProcessingError
}
public enum ErrorType
{
Default,
[JsonProperty("api_connection_error")]
ApiConnectionError,
[JsonProperty("api_error")]
ApiError,
[JsonProperty("authentication_error")]
AuthenticationError,
[JsonProperty("card_error")]
CardError,
[JsonProperty("invalid_request_error")]
InvalidRequestError,
[JsonProperty("rate_limit_error")]
RateLimitError
}
我想坚持使用Enums而不是字符串 对此有什么好的解决方法?
答案 0 :(得分:2)
你有几个问题:
您需要使用StringEnumConverter
将枚举序列化为字符串。
而不是[JsonProperty("enum_name")]
您需要使用[EnumMember(Value = "enum_name")]
来指定重新映射的枚举名称。您可能还想添加[DataContract]
以与数据协定序列化程序完全兼容。
将JSON字符串解析为JToken
后,使用JToken.ToObject()
或JToken.CreateReader()
对其进行反序列化效率会更高。无需序列化为字符串,然后从头开始重新解析。
因此,您的类型应如下所示:
[DataContract]
public enum ErrorCode
{
Default,
[EnumMember(Value = "invalid_number")]
InvalidNumber,
[EnumMember(Value = "invalid_expiry_month")]
InvalidExpiryMonth,
[JsonProperty("invalid_expiry_year")]
InvalidExpiryYear,
[EnumMember(Value = "invalid_cvc")]
InvalidCvc,
[EnumMember(Value = "incorrect_number")]
IncorrectNumber,
[EnumMember(Value = "expired_card")]
ExpiredCard,
[EnumMember(Value = "incorrect_cvc")]
IncorrectCvc,
[EnumMember(Value = "incorrect_zip")]
IncorrectZip,
[EnumMember(Value = "card_declined")]
CardDeclined,
[EnumMember(Value = "missing")]
Missing,
[EnumMember(Value = "processing_error")]
ProcessingError
}
public class Error
{
public ErrorType type { get; set; }
public string message { get; set; }
}
[DataContract]
public enum ErrorType
{
Default,
[EnumMember(Value = "api_connection_error")]
ApiConnectionError,
[EnumMember(Value = "api_error")]
ApiError,
[EnumMember(Value = "authentication_error")]
AuthenticationError,
[EnumMember(Value = "card_error")]
CardError,
[EnumMember(Value = "invalid_request_error")]
InvalidRequestError,
[EnumMember(Value = "rate_limit_error")]
RateLimitError
}
你的映射器:
public static class JsonMapper
{
private static JsonReader CreateReader(string json, string parentToken)
{
if (string.IsNullOrEmpty(parentToken))
return new JsonTextReader(new StringReader(json));
else
{
var token = JToken.Parse(json).SelectToken(parentToken);
return token == null ? null : token.CreateReader();
}
}
public static T MapFromJson<T>(string json, string parentToken = null)
{
var settings = new JsonSerializerSettings { Converters = new [] { new StringEnumConverter() } };
using (var reader = CreateReader(json, parentToken))
{
if (reader == null)
return default(T);
return JsonSerializer.CreateDefault(settings).Deserialize<T>(reader);
}
}
}