-1

I'm receiving a JSON string in C#, like this :

{
    "Id": "617723",
    "Acronym": "",
    "FirstName": "XXXXX",
    "LastName": "XXXXX",
    "Groupe": {
        "Code": "XXXXX",
        "Traductions": {
            "French": "",
            "English": "XXXXX"
        }
    },
    "BusinessUnit": {
        "Code": "XXXXX",
        "Traductions": {
            "French": "",
            "English": "XXXXX"
        }
    },
    "Team": {
        "Code": null,
        "Traductions": {
            "French": "",
            "English": null
        }
    },
    "Title": {
        "Code": null,
        "Traductions": {
            "French": "",
            "English": "XXXXX"
        }
    },
    "Title2": {
        "Code": null,
        "Traductions": {
            "French": "",
            "English": null
        }
    },
    "JobCategory": {
        "Code": "XXXXX",
        "Traductions": {
            "French": "",
            "English": "XXXXX"
        }
    },
    "PhoneList": [],
    "DateHired": "XXXXX",
    "DateTerminated": "XXXXX",
    "Gender": "XXXXX",
    "ManagerId": "XXXXX",
    "ManagerAcronym": "XXXXX",
    "IsManager": false,
    "Email": null,
    "CarLicense": null,
    "MyTeam": [],
    "HomeBase": {
        "Code": "XXXXX",
        "Traductions": {
            "French": "XXXXX",
            "English": "XXXXX"
        }
    },
    "Country": {
        "Code": "XXXXX",
        "Traductions": {
            "French": "XXXXXX",
            "English": "XXXXX"
        }
    },
    "State": {
        "Code": "XXXXX",
        "Traductions": {
            "French": "XXXXX",
            "English": "XXXXX"
        }
    },
    "City": {
        "Code": "XXXXX",
        "Traductions": {
            "French": "XXXXX",
            "English": "XXXXX"
        }
    },
    "ShirtSize": "",
    "LanguageAddressBook": "XXXXX",
    "LanguagePrefered": null,
    "Local": null,
    "Mailbox": null,
    "HomeBusinessUnit": "1",
    "JobType": "XXXXXX",
    "UnionCode": "",
    "ProfessionalTitle": {
        "Code": null,
        "Traductions": {
            "French": "",
            "English": null
        }
    },
    "IconEmailActif": true,
    "IconSkypeActif": true
}

I want to convert it in a C# Object, so I made my Model like this :

public class UsersJson
{
    public string Acronym { get; set; }

    public string[] BusinessUnit { get; set; }

    public string CarLicense { get; set; }

    public string[] City { get; set; }

    public string[] Country { get; set; }

    public string DateHired { get; set; }

    public string DateTerminated { get; set; }

    public string Email { get; set; }

    public string FirstName { get; set; }

    public string Gender { get; set; }

    public string[] Groupe { get; set; }

    public string[] HomeBase { get; set; }

    public string HomeBusinessUnit { get; set; }

    public bool IconEmailActif { get; set; }

    public bool IconSkypeActif { get; set; }

    public string Id { get; set; }

    public bool IsManager { get; set; }

    public string[] JobCategory { get; set; }

    public string JobType { get; set; }

    public string LanguageAddressBook { get; set; }

    public string LanguagePrefered { get; set; }

    public string LastName { get; set; }

    public string Local { get; set; }

    public string Mailbox { get; set; }

    public string ManagerAcronym { get; set; }

    public string ManagerId { get; set; }

    public string[] MyTeam { get; set; }

    public string[] PhoneList { get; set; }

    public string[] ProfessionalTitle { get; set; }

    public string ShirtSize { get; set; }

    public string[] State { get; set; }

    public string[] Team { get; set; }

    public string[] Title { get; set; }

    public string[] Title2 { get; set; }

    public string UnionCode { get; set; }
}

When I try to Deserialize it into a List<UsersJson>, I get the following error :

Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.String[]' 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 '[0].Groupe.Code', line 1, position 87."

So, how should I declare the property Group if it's not a string[] ?

phuzi
  • 12,078
  • 3
  • 26
  • 50
Alex Caron
  • 23
  • 8
  • 1
    Welcome to Stack Overflow. Your JSON doesn't represent a list of users - it represents a *single* user. If you're still having trouble with that, it would be very helpful if you'd reduce this to a minimal example - I don't think you need 30+ properties to demonstrate the problem, and the shorter it is, the easier it'll be for people to help you. – Jon Skeet Apr 16 '18 at 13:42
  • Are you using .net core or standard .net ? – Danijel Boksan Apr 16 '18 at 13:43
  • Please check this link, maybe can help you: https://stackoverflow.com/questions/25052293/deserialize-json-to-c-sharp-classes – Danijel Boksan Apr 16 '18 at 13:44
  • 2
    But note that the "Team" property (for example) really isn't an array of strings - it's a subobject that you should probably model as a separate class. (It looks like you could use that class for a lot of your properties.) – Jon Skeet Apr 16 '18 at 13:45
  • I'm using standard .net – Alex Caron Apr 16 '18 at 13:45
  • use http://json2csharp.com/ ... looks like the model is incorrect – Rahul Apr 16 '18 at 13:49
  • Is their a reason why, for this every day dupe, you always talk about Json2csharp when Visual studio got Special past Json to class? – Drag and Drop Apr 16 '18 at 13:52
  • @DragandDrop that's available to newer version of VS (I believe 2017) ... what if OP using a older one? – Rahul Apr 16 '18 at 14:00
  • 2012 and 2013 has it too. from memory if target Framework is <3.5 you dont have access to parse json but only parse xml. But I got your point. still 60% of the daily question under the c#+json tags looks dupe to me. – Drag and Drop Apr 16 '18 at 14:15

4 Answers4

1

Use the correct classes. I followed the steps outlined here and refactored a bit:

RootObject r = JsonConvert.DeserializeObject<RootObject>(json);

public class Traductions
{
    public string French { get; set; }
    public string English { get; set; }
}

public class Groupe
{
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class BusinessUnit
{
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class Team
{
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class Title
{
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class JobCategory
{
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class HomeBase
{
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class Country
{
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class State
{
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class City
{
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class ProfessionalTitle
{
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class RootObject
{
    public string Id { get; set; }
    public string Acronym { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Groupe Groupe { get; set; }
    public BusinessUnit BusinessUnit { get; set; }
    public Team Team { get; set; }
    public Title Title { get; set; }
    public Title Title2 { get; set; }
    public JobCategory JobCategory { get; set; }
    public List<object> PhoneList { get; set; }
    public string DateHired { get; set; }
    public string DateTerminated { get; set; }
    public string Gender { get; set; }
    public string ManagerId { get; set; }
    public string ManagerAcronym { get; set; }
    public bool IsManager { get; set; }
    public string Email { get; set; }
    public string CarLicense { get; set; }
    public List<object> MyTeam { get; set; }
    public HomeBase HomeBase { get; set; }
    public Country Country { get; set; }
    public State State { get; set; }
    public City City { get; set; }
    public string ShirtSize { get; set; }
    public string LanguageAddressBook { get; set; }
    public string LanguagePrefered { get; set; }
    public string Local { get; set; }
    public string Mailbox { get; set; }
    public string HomeBusinessUnit { get; set; }
    public string JobType { get; set; }
    public string UnionCode { get; set; }
    public ProfessionalTitle ProfessionalTitle { get; set; }
    public bool IconEmailActif { get; set; }
    public bool IconSkypeActif { get; set; }
}
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • The issue with using a tool is that it spits out code without following some good practices. A tool can get you started but I wouldn't use this in production as it violates one good rule, DRY. Really only 2 extra classes are needed. – Ron Beyer Apr 16 '18 at 14:15
  • I tend to agree, but what if a property is added to one class. It might influence others. We can only assume they are actually the same type on the other end... – Patrick Hofman Apr 16 '18 at 14:22
0

You'll need another couple of classes with the Code and Traductions properties.

public class Groupe {
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class Traductions {
    public string French { get; set; }
    public string English { get; set; }
}

Use Groupe in place of string[] in your base class and you should be golden :)

phuzi
  • 12,078
  • 3
  • 26
  • 50
0

The accepted answer works, but I feel it has a lot of code-repetition. You only need two other model classes for this to work:

public class Traductions
{
    public string French { get; set; }
    public string English { get; set; }
}

public class CodeTraduction
{
    public string Code { get; set; }
    public Traductions Traductions { get; set; }
}

public class RootObject
{
    public string Id { get; set; }
    public string Acronym { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public CodeTraduction Groupe { get; set; }
    public CodeTraduction BusinessUnit { get; set; }
    public CodeTraduction Team { get; set; }
    public CodeTraduction Title { get; set; }
    public CodeTraduction Title2 { get; set; }
    public CodeTraduction JobCategory { get; set; }
    public List<object> PhoneList { get; set; }
    public string DateHired { get; set; }
    public string DateTerminated { get; set; }
    public string Gender { get; set; }
    public string ManagerId { get; set; }
    public string ManagerAcronym { get; set; }
    public bool IsManager { get; set; }
    public string Email { get; set; }
    public string CarLicense { get; set; }
    public List<object> MyTeam { get; set; }
    public CodeTraduction HomeBase { get; set; }
    public CodeTraduction Country { get; set; }
    public CodeTraduction State { get; set; }
    public CodeTraduction City { get; set; }
    public string ShirtSize { get; set; }
    public string LanguageAddressBook { get; set; }
    public string LanguagePrefered { get; set; }
    public string Local { get; set; }
    public string Mailbox { get; set; }
    public string HomeBusinessUnit { get; set; }
    public string JobType { get; set; }
    public string UnionCode { get; set; }
    public CodeTraduction ProfessionalTitle { get; set; }
    public bool IconEmailActif { get; set; }
    public bool IconSkypeActif { get; set; }
}

Using your example JSON, you would deserialize it like this:

var item = JsonConvert.DeserializeObject<RootObject>(json);

You can create separate classes if you wish, but keep a single base-class CodeTraduction, for example:

public class Groupe : CodeTraduction
{
    //Add any "Groupe" specific properties here
}
Ron Beyer
  • 11,003
  • 1
  • 19
  • 37
0

For future reference, you can also use Paste Special. You copy the JSON file(Ctrl+C) and add a new class file, if you dont already have one. Then you go in to Edit(at the top left of VS) and hover your cursor over Paste Special, you will get two options, one for XML as Class or JSON as Class. Hope it helps you and others in the future. :)