Reputation: 3
I have class named ResponseModel
and one object inside that class named Errors
refer to the class ErrorsResponseModel
, and that class has bunch of objects which have List<string>
data type . I would like to know on how to accessing the List<string>
objects without going through like: VariableClassA.ObjectOfClassAWhichReferToTheClassB.FirstListOfString
and VariableClassA.ObjectOfClassAWhichReferToTheClassB.SecondListOfString
, the data of List<string>
objects comes from the JSON data.
I have tried only to access one object per one object as I am not really sure on how to do generic without going through one object per one object, which is if I update the model of class B itself, then I need to make sure that I didn't missed out the necessary checking of that newly created object inside class B.
Here is the code of the model:
public sealed class ResponseModel
{
public ErrorsResponseModel Errors { get; set; }
}
public sealed class ErrorsResponseModel
{
public List<string> Username { get; set; }
public List<string> Password { get; set; }
public List<string> Nickname { get; set; }
}
Here is what I have tried so far:
string jsonData = "{"Errors":{"Username":["The username field is required."],"Password":["The password field is required."],"Nickname":["The nickname field is required."]}}";
var jsonConvertedData = JsonConvert.DeserializeObject<ResponseModel>(jsonData);
var usernameErrors = jsonConvertedData.Errors.Username;
var passwordErrors = jsonConvertedData.Errors.Password;
var nicknameErrors = jsonConvertedData.Errors.Nickname;
I expect to loop any object of class ErrorsResponseModel
that the length of List<string>
inside that class is more than 0 . I can't change the response data from the JSON, as it is comes from the third party.
EDIT: I have tried the following in JavaScript and it works, how can I do the same in C#?
in C#, I return to the front end like using the following return Json(jsonConvertedData)
, and in frontend, I do like the following:
$.ajax({
..... the AJAX settings
success: function (data) {
$.each(data.Errors, function (i, v) {
if (v.length > 0) {
console.log(v);
}
});
}
The above code in Javascript is looping through the message inside each object inside ErrorsResponseModel
and read it through to the console.
Upvotes: 0
Views: 1020
Reputation: 27154
Let ErrorsResponseModel
inherit Dictionary
public sealed class ErrorsResponseModel : Dictionary<string, List<string>>
{
//If you still want to access data with property.
public List<string> Username => this["Username"];
...
}
Now you can loop through Errors
like a normal dictionary
foreach (var item in jsonConvertedData.Errors)
if(item.Value.Count > 0)
Console.WriteLine($"{item.Key} => {item.Value[0]}");
dynamic
is another choice
var jsonConvertedData = JsonConvert.DeserializeObject<dynamic>(jsonData);
foreach (var item in jsonConvertedData.Errors)
if(item.Count > 0)
foreach(var v in item.Value)
Console.WriteLine(v);
Upvotes: 1
Reputation: 37050
One way to do this would be to create a class to hold the related data, for example:
class User
{
public string Name { get; set; }
public string Nickname { get; set; }
public string Password { get; set; }
}
Then we can make a method that populates a list of this class from the ErrorsResponseModel
class (after first validating that the counts of all the lists are the same):
public List<User> GetUsers(ErrorsResponseModel errors)
{
if (errors == null || errors.Username == null) return null;
if (errors.Username.Count == 0) return new List<User>();
if (errors.Nickname?.Count != errors.Password?.Count ||
errors.Password?.Count != errors.Username.Count)
{
throw new InvalidDataException("Unequal number of Usernames/Passwords/Nicknames");
}
return errors.Username
.Select((userName, index) =>
new User
{
Name = userName,
Nickname = errors.Nickname[index],
Password = errors.Password[index]
}).ToList();
}
Upvotes: 0