Reputation: 525
What is the best way to deserialize the following JSON response into a generic object? For example I would like to access the response message and a the list of errors (and accessing the field name and error message of it).
{
"message": "The given data was invalid.",
"errors": {
"name": [
"Name is required."
],
"gender": [
"Gender is required."
],
"date_of_birth": [
"Date of birth is required."
]
}
}
Edit:
I would like to access the JSON object in a way something like this
string message = genericObject.message
foreach (error errorElement in genericObject.errors)
{
string errorField = errorElement.fieldName;
string errorDescription = errorElement.errorMessage;
}
Edit 2:
I don't know the possible error fields beforehand.
Upvotes: 1
Views: 2908
Reputation: 6304
There are many ways to do this.
The System.Web.Helpers
assembly contains the Json
class which you can do:
dynamic decodedObject = Json.Decode(json);
Another way would be to use the Newtonsoft.Json nuget package:
var deserializedObject = JsonConvert.DeserializeObject<dynamic>(json);
Upvotes: 2
Reputation: 391724
Since you mention that you do not know which "error fields" will be present, a dictionary is the best way to go.
Here's a simple example:
void Main()
{
string json = File.ReadAllText(@"d:\temp\test.json");
var response = JsonConvert.DeserializeObject<Response>(json);
response.Dump();
}
public class Response
{
public string Message { get; set; }
public Dictionary<string, List<string>> Errors { get; }
= new Dictionary<string, List<string>>();
}
When executing this in LINQPad, I get this output:
You can even add your own code from your question:
string json = File.ReadAllText(@"d:\temp\test.json");
var genericObject = JsonConvert.DeserializeObject<Response>(json);
string message = genericObject.Message;
foreach (var errorElement in genericObject.Errors) // see note about var below
{
string errorField = errorElement.Key;
string errorDescription = errorElement.Value.FirstOrDefault(); // see below
}
Note 1: The result of iterating a dictionary is a KeyValuePair<TKey, TValue>
, in this case it would be a KeyValuePair<string, List<string>>
.
Note 2: You've shown JSON having an array for each field, so errorElement.errorMessage
isn't going to work properly since you may have multiple error messages.
You can nest some loops, however, to process them all:
string message = genericObject.Message;
foreach (var errorElement in genericObject.Errors) // see note about var below
{
string errorField = errorElement.Key;
foreach (string errorDescription in errorElement.Value)
{
// process errorField + errorDescription here
}
}
Upvotes: 2
Reputation: 2393
you would have to create the following classes:
RootObject.cs
containing the following properties:
public class RootObject
{
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("errors")]
public Errors Errors { get; set; }
}
Errors.cs
, containing the following properties:
public class Errors
{
[JsonProperty("name")]
public string[] Name { get; set; }
[JsonProperty("gender")]
public string[] Gender { get; set; }
[JsonProperty("date_of_birth")]
public string[] DateOfBirth { get; set; }
}
And then you read the whole thing like this:
var inputObj = JsonConvert.DeserializeObject<RootObject>(json);
Where inputObj
will be of type RootObject
and json
is the JSON you are receiving.
If you have implemented this correctly, use it like this:
var message = inputObj.Message;
var nameErrors = inputObj.Errors;
var firstNameError = inputObj.Errors.Name[0];
Here is a visual:
Showing the whole object, filled with the properties:
If you have any questions feel free to ask.
Upvotes: 1
Reputation: 319
If you are willing to use Newtonsoft.Json you can use:
var json = JsonConvert.DeserializeObject<dynamic>(originalJson);
Upvotes: 1