It is unusual to see a success and error result returned using the same property name in a JSON result. This does not mean that it can not be handled.
You have tagged your question with
ASP.NET5, so I am going to focus on a
.Net 5.0+ solution, so I will be using
System.Text.Json
for deserialization. I will do this using a Console app.
As the
info
property can be 2 different types, we need to enable support. To do this, I am going to use
JsonElement
to hold the
info
property data, then deserialize based on the result code - 200 = success, 400 = bad request.
public class Output
{
public int id { get; set; }
public string msg { get; set; }
public string trans_id { get; set; }
public JsonElement info { get; set; }
}
Next we need a class to hold the
Success and
Error results.
public class Info
{
public Data? Data { get; set; }
public List<String>? Errors { get; set; }
}
And we need a class to hold the success data:
public class Data
{
public string id { get; set; }
public string number { get; set; }
}
Now we are ready to process and deserialize.
Info? JsonToInfo(string rawJson)
{
Output? result = JsonSerializer.Deserialize<Output>(rawJson);
return result?.id switch
{
200 => new Info
{
Data = result.info.Deserialize<Data>(jsonSerializerOptions)
},
400 => new Info
{
Errors = result.info.Deserialize<List<string>>(jsonSerializerOptions)
},
_ => null
};
}
Here we deserialize the returned json, and then deserialize the
info
property and return that dependant on the return code in the root
id
property.
Here is the complete test project:
using System.Text.Json;
string rawJsonSuccess =
""""
{
"id": 200,
"msg": "Successful",
"trans_id": "415",
"info": {
"id": "41",
"number": "3889 is already exists"
}
}
"""";
string rawJsonBadRequest =
""""
{
"id": 400,
"msg": "Bad Request",
"trans_id": "CLIENTAPI202306050146459",
"info": [
"state : value must be a valid string",
"city : value must be a valid string"
]
}
"""";
JsonSerializerOptions? jsonSerializerOptions = new();
Info? successResult = JsonToInfo(rawJsonSuccess);
DumpSuccess(successResult);
Console.WriteLine("----------");
Console.WriteLine();
void DumpSuccess(Info? info)
{
if (info is null)
{
Console.WriteLine("No Info data");
return;
}
Console.WriteLine($"ID: {info.Data!.id}");
Console.WriteLine($"NUMBER: {info.Data!.number}");
}
Info? badRequestResult = JsonToInfo(rawJsonBadRequest);
DumpBadRequest(badRequestResult);
void DumpBadRequest(Info? info)
{
if (info is null)
{
Console.WriteLine("No Error data");
return;
}
Console.WriteLine("Errors returned:");
foreach (string error in info.Errors!)
{
Console.WriteLine($" > {error}");
}
}
Info? JsonToInfo(string rawJson)
{
Output? result = JsonSerializer.Deserialize<Output>(rawJson);
return result?.id switch
{
200 => new Info
{
Data = result.info.Deserialize<Data>(jsonSerializerOptions)
},
400 => new Info
{
Errors = result.info.Deserialize<List<string>>(jsonSerializerOptions)
},
_ => null
};
}
public class Output
{
public int id { get; set; }
public string? msg { get; set; }
public string? trans_id { get; set; }
public JsonElement info { get; set; }
}
public class Info
{
public Data? Data { get; set; }
public List<string>? Errors { get; set; }
}
public class Data
{
public string? id { get; set; }
public string? number { get; set; }
}
and the output:
ID: 41
NUMBER: 3889 is already exists
----------
Errors returned:
> state : value must be a valid string
> city : value must be a valid string
UPDATE
If you want the header/root data, you can move the
Info
class into the
Output
class:
public class Output
{
public int id { get; set; }
public string? msg { get; set; }
public string? trans_id { get; set; }
public JsonElement info { get; set; }
[JsonIgnore]
public Info? InfoData { get; set; }
}
Then deserialization would be:
Output? DeserializeJson(string rawJson)
{
Output? result = JsonSerializer.Deserialize<Output>(rawJson);
if (result is null)
return null;
result.InfoData = result?.id switch
{
200 => new Info
{
Data = result.info.Deserialize<Data>(jsonSerializerOptions)
},
400 => new Info
{
Errors = result.info.Deserialize<List<string>>(jsonSerializerOptions)
},
_ => null
};
return result;
}
Here is the full project:
using System.Text.Json;
using System.Text.Json.Serialization;
string rawJsonSuccess =
""""
{
"id": 200,
"msg": "Successful",
"trans_id": "415",
"info": {
"id": "41",
"number": "3889 is already exists"
}
}
"""";
string rawJsonBadRequest =
""""
{
"id": 400,
"msg": "Bad Request",
"trans_id": "CLIENTAPI202306050146459",
"info": [
"state : value must be a valid string",
"city : value must be a valid string"
]
}
"""";
JsonSerializerOptions? jsonSerializerOptions = new();
Output? successResult = DeserializeJson(rawJsonSuccess);
DumpState(successResult);
DumpSuccess(successResult);
Console.WriteLine("----------");
Console.WriteLine();
void DumpSuccess(Output? output)
{
if (output is null)
{
Console.WriteLine("No Output data");
return;
}
if (output.InfoData is null)
{
Console.WriteLine("No Info data");
return;
}
Console.WriteLine($"ID: {output.InfoData.Data!.id}");
Console.WriteLine($"NUMBER: {output.InfoData.Data!.number}");
}
Output? badRequestResult = DeserializeJson(rawJsonBadRequest);
DumpState(badRequestResult);
DumpBadRequest(badRequestResult);
void DumpBadRequest(Output? output)
{
if (output is null)
{
Console.WriteLine("No Output data");
return;
}
if (output.InfoData is null)
{
Console.WriteLine("No Error data");
return;
}
Console.WriteLine("Errors returned:");
foreach (string error in output.InfoData.Errors!)
{
Console.WriteLine($" > {error}");
}
}
void DumpState(Output? output)
{
if (output is null)
{
Console.WriteLine("No Output data");
return;
}
Console.WriteLine($"RESULT ID: {output.id}");
Console.WriteLine($"MESSAGE: {output.msg}");
Console.WriteLine($"TRANS_ID: {output.trans_id}");
}
Output? DeserializeJson(string rawJson)
{
Output? result = JsonSerializer.Deserialize<Output>(rawJson);
if (result is null)
return null;
result.InfoData = result?.id switch
{
200 => new Info
{
Data = result.info.Deserialize<Data>(jsonSerializerOptions)
},
400 => new Info
{
Errors = result.info.Deserialize<List<string>>(jsonSerializerOptions)
},
_ => null
};
return result;
}
public class Output
{
public int id { get; set; }
public string? msg { get; set; }
public string? trans_id { get; set; }
public JsonElement info { get; set; }
[JsonIgnore]
public Info? InfoData { get; set; }
}
public class Info
{
public Data? Data { get; set; }
public List<string>? Errors { get; set; }
}
public class Data
{
public string? id { get; set; }
public string? number { get; set; }
}
and the output:
RESULT ID: 200
MESSAGE: Successful
TRANS_ID: 415
ID: 41
NUMBER: 3889 is already exists
----------
RESULT ID: 400
MESSAGE: Bad Request
TRANS_ID: CLIENTAPI202306050146459
Errors returned:
> state : value must be a valid string
> city : value must be a valid string