Reputation: 255
I'm implementing an external API who give me a response like this if is OK:
{
status: "success",
answer: {
token: "tokenGenerated..."
}
}
Or like this if I get an error:
{
status: "ERROR",
answer: {
errorCode: "error code"
errorMessage: "error message"
}
}
I'm trying to deserialize the response in two differents class, one for the OK response, and another for the ERROR response. I'm doing something like this:
public class Response
{
[JsonProperty("status")]
private string Status { get; set; }
public bool IsSuccess => Status != "ERROR";
[JsonProperty("answer")]
public object Response { get; set; }
}
public class ResponseError : Response
{
[JsonProperty("errorCode")]
public string ErrorCode { get; set; }
[JsonProperty("errorMessage")]
public string ErrorMessage { get; set; }
}
public class ResponseOk : Response
{
[JsonProperty("token")]
public string Token { get; set; }
}
And when I get the response I do this:
var readResponse = await response.Content.ReadAsStringAsync();
var deserializedResponse = JsonConvert.DeserializeObject<Response>(readResponse);
if (deserializedResponse.IsSuccess)
return JsonConvert.DeserializeObject<ResponseOk>(readResponse);
else
return JsonConvert.DeserializeObject<ResponseError>(readResponse);
In my method I return a object. My problem is, for example, if I get an OK status, the property Status is well implemented, and in the Response property I get the "token: "tokenhere"", not in the Token property.
And if I try to put inside the Resposne class the Token property and the errors properties, I need to apply the JsonProperty("answer") in both cases and of course I get an exception.
There's a better way of implementing this for my case? Thx.
Upvotes: 1
Views: 1417
Reputation: 7541
You can define your classes like this (haven't tested):
public class Response
{
[JsonProperty("status")]
private string Status { get; set; }
public bool IsSuccess => Status != "ERROR";
}
public class ResponseError : Response
{
[JsonProperty("answer")]
public ResponseErrorContent answer { get; set; }
}
public class ResponseErrorContent
{
[JsonProperty("errorCode")]
public string ErrorCode { get; set; }
[JsonProperty("errorMessage")]
public string ErrorMessage { get; set; }
}
public class ResponseOk : Response
{
[JsonProperty("answer")]
public ResponseOkContent answer { get; set; }
}
public class ResponseOkContent
{
[JsonProperty("token")]
public string Token { get; set; }
}
Upvotes: 0
Reputation: 12171
You map answer
object in JSON to Response
property in Response
class.
Having this class:
public class ResponseOk : Response
{
[JsonProperty("token")]
public string Token { get; set; }
}
you expect a token
property in JSON as root property, but you have token
inside answer
so this mapping won't work.
You will have the same issue when you get an error - ErrorCode
and ErrorMessage
also won't be set because you map them to root propeties.
You can change your classes to:
public class Response
{
[JsonProperty("status")]
private string Status { get; set; }
public bool IsSuccess => Status != "ERROR";
[JsonProperty("answer")]
public Answer Response { get; set; } // can be just renamed to "Answer"
}
public class Answer
{
[JsonProperty("errorCode")]
public string ErrorCode { get; set; }
[JsonProperty("errorMessage")]
public string ErrorMessage { get; set; }
[JsonProperty("token")]
public string Token { get; set; }
}
And now you can check the IsSuccess
in Response
class and decide what to use - Token
or error properties.
Upvotes: 1