0

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?

Sachihiro
  • 1,597
  • 2
  • 20
  • 46
  • Where do you get this jsonString from? does it send any more information with the jsonString or its just the jsonString? – Pouya Hashemi Sep 06 '22 at 16:59

2 Answers2

1

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.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
0

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.

David Guida
  • 950
  • 9
  • 19