0

I'm calling a third-party API that returns a generic result based on a boolean "Success" field. The result is a known type class based on the result response.

I'm doing a very stupid way of deserializing the class to an object type and reading the result.

After reading the result I will serialize the object to JSON again and deserialize the object back to the corresponding correct result/known data type.

The question I would like to ask is, what is the efficient or better way to achieve this.

Sample Response from third party API

if success is false

    {
        "Success": false,
        "Result": 
        {
            "ErrorCode": "1",
            "ErrorMessage": "Request is unsuccessful."
        }
    }

If success is true

    {
        "Success": true,
        "Result": 
        {
            "UserID": "xxxxx",
            "UserName": "yyyyy",
            "UserAge": 60
        }
    }

My Code

My Calling Method (How to improve this calling method???)

var request = new RequestModel ("user1", "password1");
var data = await CallThirdPartyAPI(request);
//At this point of time, this `data` is a `Message<object>` data type
if (data.Success)
{
    var passResult = JsonConvert.SerializeObject(data); //Serialize object type back to JSON 
    var passObject = JsonConvert.DeserializeObject<Message<SuccessResponse>>(passResult); //Deserialize object back to known data type
}
else
{
    var failResult = JsonConvert.SerializeObject(data); //Serialize object type back to JSON
    var failObject = JsonConvert.DeserializeObject<Message<FailResponse>>(failResult); //Deserialize object back to known data type
}

API Method

public async Task<Message<object>> CallThirdPartyAPI(RequestModel requestModel)
{
    var requestUrl = CreateRequestUri(string.Format(System.Globalization.CultureInfo.InvariantCulture,
        "api/thirdpartyapi/"));
    var result =  await PostAsync<object, requestModel>(requestUrl, requestModel);
    return result;
}


// Common method for making POST calls
private async Task<Message<T1>> PostAsync<T1, T2>(Uri requestUrl, T2 content)
{                 
    var response = await _httpClient.PostAsync(requestUrl.ToString(), CreateHttpContent<T2>(content));
    response.EnsureSuccessStatusCode();
    var data = await response.Content.ReadAsStringAsync();
    var result =  JsonConvert.DeserializeObject<Message<T1>>(data);
    return result;
}

DTO

public class Message<T>
{
    [DataMember(Name = "Success")]
    public bool Success { get; set; }

    [DataMember(Name = "Result")]
    public T Result { get; set; }
}

public class FailResponse
{
    public string ErrorCode { get; set; }
    public string ErrorMessage { get; set; }
}

public class SuccessResponse
{
    public string UserId{ get; set; }
    public string UserName { get; set; }
    public int UserAge{ get; set; }
}

public class RequestModel
{
 public string UserName { get; set; }
 public string Password { get; set; }
}
Kit
  • 20,354
  • 4
  • 60
  • 103
hongguan
  • 520
  • 2
  • 12
  • 1
    Consider adding all five properties (`ErrorCode` through to `UserAge`) to a single class. Then add methods to the class to convert to the different specific types (i.e. error or success) as needed. – mjwills Jun 13 '19 at 03:24
  • 1
    You can use a `JsonConverter` as shown in [Deserializing polymorphic json classes without type information using json.net](https://stackoverflow.com/q/19307752/10263) – Brian Rogers Jun 13 '19 at 04:15

0 Answers0