Home > Software engineering >  Mapping API to Object C#
Mapping API to Object C#

Time:11-23

I tried to map the API to an object. But got an error:

Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List'1[APIWebApp.Models.UserModel]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path '@count', line 2, position 11.'

Here is my code:

Function to run the mapping:

public List<UserModel> GetUserList()
        {
            try
            {
                using (WebClient webClient = new WebClient())
                {
                    webClient.Credentials = new NetworkCredential("un", "pw");
                    webClient.BaseAddress = StaticItems.EndPoint;
                    var json = webClient.DownloadString("userlist?view=expand");
                    var list = JsonConvert.DeserializeObject < List<UserModel>>(json);
                    return list.ToList();
                }
            }
            catch (WebException ex)
            {
                throw ex;
            }
        }

public static class StaticItems
{
    public static string EndPoint = "https://XXXXXX";
}

Here is the model:

namespace APIWebApp.Models
{
    public class UserModel
    {
        public int count { get; set; }
        public int start { get; set; }
        public int totalcount { get; set; }
        public object[] Messages { get; set; }
        public string ResourceName { get; set; }
        public int ReturnCode { get; set; }
        public Content[] content { get; set; }
    }
    
    public class Content
    {
        public Users user { get; set; }
    }

    public class Users
    {
        public string name { get; set; }
        public string age { get; set; }
        public string date { get; set; }
    }
}

The API json:

{
  "@count": 2,
  "@start": 1,
  "@totalcount": 2,
  "Messages": [],
  "ResourceName": "user",
  "ReturnCode": 0,
  "content": [
    {"user": {
      "name": "Eric",
      "age": "25",
      "date": "2021-10-23T11:18:10 00:00",
    }},
    {"user": {
      "name": "Paul",
      "age": "30",
      "date": "2021-10-23T11:18:10 00:00",
    }}]
}

i realy have no idea what Im doing wrong.

Thank you for your help

CodePudding user response:

If you just need the user list, just return the users

public List<User> GetUserList()
        {
            try
            {
                using (WebClient webClient = new WebClient())
                {
                    webClient.Credentials = new NetworkCredential("un", "pw");
                    webClient.BaseAddress = StaticItems.EndPoint;
                    var json = webClient.DownloadString("userlist?view=expand");
                    var list = JsonConvert.DeserializeObject<List<UserModel>>(json);
    
                    List<User> userList = new List<User>();
                    foreach (var item in list.content)
                    {
                        userList.Add(item.user);
                    }
                    return userList;
                }
            }
            catch (WebException ex)
            {
                throw ex;
            }
        }

CodePudding user response:

Welcome! The JSON being returned by your API is a UserModel and not a List<UserModel>, so first you need to Deserialize the json to UserModel. Then, you can return whatever you like from GetUsersList(), either the UserModel or the List<Users> (like below).

using (WebClient webClient = new WebClient())
    {
          webClient.Credentials = new NetworkCredential("un", "pw");
          webClient.BaseAddress = StaticItems.EndPoint;
          var json = webClient.DownloadString("userlist?view=expand");
          UserModel userModel = JsonConvert.DeserializeObject <UserModel>(json); // here
          return userModel.content.Select(c => c.user).ToList();
    }
  • Related