18

I have Json string like below

 {
"JsonValues":{

        "id": "MyID",

         "values": {
            "value1":{
                "id": "100",
                "diaplayName": "MyValue1"
            },
            "value2":{
                "id": "200",
                "diaplayName": "MyValue2"
            }
       }
}
}

I want to convert Json string to below classes

  class ValueSet
   {
    [JsonProperty("id")]
    public string id
    {
        get;
        set;
    }
    [JsonProperty("values")]
    public List<Value> values
    {
        get;
        set;
    }
  }

class Value
{
    public string id
    {
        get;
        set;
    }
    public string DiaplayName
    {
        get;
        set;
    }
}

My deserialization code is

JavaScriptSerializer js = new JavaScriptSerializer();
        StreamReader sr = new StreamReader(@"ValueSetJsonString.txt");
        string jsonString = sr.ReadToEnd();
        var items = JsonConvert.DeserializeObject<ValueSet>(jsonString);

But I am getting null values after serialization, How i can solve this?

niknowj
  • 977
  • 4
  • 19
  • 37
  • Check this solution: https://stackoverflow.com/questions/14528385/how-to-convert-json-object-to-javascript-array – Nyweron May 16 '18 at 12:50

9 Answers9

22

As others have already pointed out, the reason you are not getting the results you expect is because your JSON does not match the class structure that you are trying to deserialize into. You either need to change your JSON or change your classes. Since others have already shown how to change the JSON, I will take the opposite approach here.

To match the JSON you posted in your question, your classes should be defined like those below. Notice I've made the following changes:

  1. I added a Wrapper class corresponding to the outer object in your JSON.
  2. I changed the Values property of the ValueSet class from a List<Value> to a Dictionary<string, Value> since the values property in your JSON contains an object, not an array.
  3. I added some additional [JsonProperty] attributes to match the property names in your JSON objects.

Class definitions:

class Wrapper
{
    [JsonProperty("JsonValues")]
    public ValueSet ValueSet { get; set; }
}

class ValueSet
{
    [JsonProperty("id")]
    public string Id { get; set; }
    [JsonProperty("values")]
    public Dictionary<string, Value> Values { get; set; }
}

class Value
{
    [JsonProperty("id")]
    public string Id { get; set; }
    [JsonProperty("diaplayName")]
    public string DisplayName { get; set; }
}

You need to deserialize into the Wrapper class, not the ValueSet class. You can then get the ValueSet from the Wrapper.

var valueSet = JsonConvert.DeserializeObject<Wrapper>(jsonString).ValueSet;

Here is a working program to demonstrate:

class Program
{
    static void Main(string[] args)
    {
        string jsonString = @"
        {
            ""JsonValues"": {
                ""id"": ""MyID"",
                ""values"": {
                    ""value1"": {
                        ""id"": ""100"",
                        ""diaplayName"": ""MyValue1""
                    },
                    ""value2"": {
                        ""id"": ""200"",
                        ""diaplayName"": ""MyValue2""
                    }
                }
            }
        }";

        var valueSet = JsonConvert.DeserializeObject<Wrapper>(jsonString).ValueSet;

        Console.WriteLine("id: " + valueSet.Id);
        foreach (KeyValuePair<string, Value> kvp in valueSet.Values)
        {
            Console.WriteLine(kvp.Key + " id: " + kvp.Value.Id);
            Console.WriteLine(kvp.Key + " name: " + kvp.Value.DisplayName);
        }
    }
}

And here is the output:

id: MyID
value1 id: 100
value1 name: MyValue1
value2 id: 200
value2 name: MyValue2
Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
12

http://json2csharp.com/

I found the above link incredibly helpful as it corrected my C# classes by generating them from the JSON that was actually returned.

Then I called :

JsonConvert.DeserializeObject<RootObject>(jsonString); 

and everything worked as expected.

bulltorious
  • 7,769
  • 4
  • 49
  • 78
  • 1
    Thanks for that link, wish I'd seen it a few weeks back as it would have saved me a few days painful work! – guytz72 Oct 21 '20 at 22:00
  • 1
    I have been struggling with one simple List in a JSON string. Your link solved it for me. Thank you so much!!! – Zath Jun 28 '21 at 16:29
  • https://app.QuickType.io is similar, but with more features and fewer ads. They also have a plug-in for visual studio. (I have no affiliation with them) – Caius Jard Feb 04 '22 at 06:14
6

Did you check this line works perfectly & your string have value in it ?

string jsonString = sr.ReadToEnd();

if yes, try this code for last line:

ValueSet items = JsonConvert.DeserializeObject<ValueSet>(jsonString);

or if you have an array of json you can use list like this :

List<ValueSet> items = JsonConvert.DeserializeObject<List<ValueSet>>(jsonString);

good luck

M2sh
  • 741
  • 1
  • 11
  • 23
2

Your data structure and your JSON do not match.

Your JSON is this:

{
    "JsonValues":{
        "id": "MyID",
        ...
    }
}

But the data structure you try to serialize it to is this:

class ValueSet
{
    [JsonProperty("id")]
    public string id
    {
        get;
        set;
    }
    ...
}

You are skipping a step: Your JSON is a class that has one property named JsonValues, which has an object of your ValueSet data structure as value.

Also inside your class your JSON is this:

"values": { ... }

Your data structure is this:

[JsonProperty("values")]
public List<Value> values
{
    get;
    set;
}

Note that { .. } in JSON defines an object, where as [ .. ] defines an array. So according to your JSON you don't have a bunch of values, but you have one values object with the properties value1 and value2 of type Value.

Since the deserializer expects an array but gets an object instead, it does the least non-destructive (Exception) thing it could do: skip the value. Your property values remains with it's default value: null.

If you can: Adjust your JSON. The following would match your data structure and is most likely what you actually want:

{
    "id": "MyID",

     "values": [
         {
            "id": "100",
            "diaplayName": "MyValue1"
         }, {
            "id": "200",
            "diaplayName": "MyValue2"
         }
     ]
}
user2674389
  • 1,123
  • 7
  • 8
  • I changed json structure like this but still i am getting null values in object – niknowj Oct 25 '13 at 06:55
  • I overlooked this. Please note that in your C# you have `DiaplayName`, but in your JSON you have `diaplayName`. The names are case-sensetive. Either change your property name in C#, the JSON or use the `JsonPropertyAttribute` to tell the serializer the JSON name of your property. – user2674389 Oct 25 '13 at 07:14
  • 1
    Also it always would be better to be more precise with your error descriptions on StackOverflow. You get `null values in object` - exactly what is null? The entire object you get? Your list? A single property? Which property? The more precise you are, the easier people can help you (and perhaps you even notice the mistake yourself). – user2674389 Oct 25 '13 at 07:26
1

Json Convert To C# Class = https://json2csharp.com/json-to-csharp

after the schema comes out

        WebClient client = new WebClient();

        client.Encoding = Encoding.UTF8;

        string myJSON = client.DownloadString("http://xxx/xx/xx.json");

        var valueSet = JsonConvert.DeserializeObject<Root>(myJSON);

The biggest one of our mistakes is that we can't match the class structure with json.

This connection will do the process automatically. You will code it later ;) = https://json2csharp.com/json-to-csharp

that's it.

  • This answer is essentially exactly the same as bultorious' answer posted 4 years prior. The op already has the json, they don't need a snippet of code that uses old WebClient (we have HttpClientt now) to retrieve it and the rest of the answer is "use json2csharp" which was already posted. Please don't add duplicates answers – Caius Jard Feb 04 '22 at 06:19
0

you have an unmatched jSon string, if you want to convert into a list, try this

{
    "id": "MyID",

     "values": [
        {
            "id": "100",
            "diaplayName": "MyValue1",
        },
        {
            "id": "200",
            "diaplayName": "MyValue2",
        }
   ]    
}
Hiệp Lê
  • 636
  • 4
  • 8
0

This is possible too:

using System.Web.Helpers;
var listOfObjectsResult = Json.Decode<List<DataType>>(JsonData);
No Name Pro
  • 160
  • 1
  • 7
usefulBee
  • 9,250
  • 10
  • 51
  • 89
0

This takes the JsonElement and deserializes it to List of objects.

List<object> draftInvoices = JsonConvert.DeserializeObject<List<object>>(jsonDrafts.ToString());

Example:

[HttpPost]
        [Route("CreateDraft")]
        public async Task<IActionResult> CreateDraft([FromBody] JsonElement jsonDrafts)
        {
            List<object> draftInvoices = JsonConvert.DeserializeObject<List<object>>(jsonDrafts.ToString());
             
          
                for (int i = 0; i < draftInvoices.Count; i++) 
                 {
                  ........
                 }  
Stefan27
  • 845
  • 8
  • 19
-4

You may use Json.Net framework to do this. Just like this :

Account account = JsonConvert.DeserializeObject<Account>(json);

the home page : http://json.codeplex.com/

the document about this : http://james.newtonking.com/json/help/index.html#

qfocus
  • 1