I am receiving this error whenever I try to deserialize the json string below:
Error:
Additional information: Error converting value "invalid_request_error" to type 'ErrorType'. Path 'type', line 2, position 33.
Json string
{
"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/."
}
}
Code
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);
}
}
Enum
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
}
I want to stick on using Enums rather than string.
What could be the good workaround for this?
You have a few issues:
You need to use StringEnumConverter
to serialize enums as strings.
Rather than [JsonProperty("enum_name")]
you need to use [EnumMember(Value = "enum_name")]
to specify a remapped enum name. You might also want to add [DataContract]
for full compatibility with the data contract serializer.
Once you have parsed your JSON string into a JToken
, it will be more efficient to deserialize it using JToken.ToObject()
or JToken.CreateReader()
. No need to serialize to a string then re-parse from scratch.
Thus your types should look like:
[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
}
And your mapper:
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);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With