I am trying to handle response that is different from what I expect normally. Normally I would expect a response that looks like the Item model below:
public class Item
{
public string Response { get; set; }
public string StatusCode { get; set; }
}
But if the DB is down or not responding, it returns this type of answer as seen from the DbError model below:
public class DbError
{
public string Code { get; set; }
public string Title { get; set; }
public string Message { get; set; }
public string ErrorCode { get; set; }
public string Cause { get; set; }
}
Typically I would try to serialize the response like this:
Item? response = JsonSerializer.Deserialize<Item>(jsonString);
How can I try to serialize as an Item but in case that the db is returning the error, serialize with the DbError model?
CodePudding user response:
There are at least two options. Assuming default System.Text.Json
is used to handle json - either write custom converter similar to one in this answer (existence of a property should be used as discriminant not a property value as in that answer) or deserialize dynamically. For example using JsonNode
API which became available since .NET 6 (docs):
var doc = JsonSerializer.Deserialize<JsonObject>(jsonString))
if (doc.ContainsKey("response"))
{
var item = doc.Deserialize<Item>();
}
else
{
var error = doc.Deserialize<DbError>();
}
For earlier versions:
using var doc = JsonSerializer.Deserialize<JsonDocument>(jsonString);
if (doc.RootElement.TryGetProperty("response", out var _))
{
var item = doc.Deserialize<Item>();
}
else
{
var error = doc.Deserialize<DbError>();
}
If you are using Newtonsoft's Json.NET both approaches can be implemented with it too.
CodePudding user response:
you'd need what is normally called "envelope". Don't return your item directly, but wrap it into another object. Something like this:
public class Envelope<T>
{
public T Data {get;}
public Error Error {get;}
public bool IsSuccessful => (this.Error is null);
}
your API consumer would have to check if IsSuccessful
is true and otherwise inspect the contents of the Error
property.