1

I am trying to bind a drop-down with these lists in my View. Not able to convert the below JSON collections to LISTS.

My JSON string is in this format:

 ["AppTypes",
 [
    {
        "AppTypeID": "5136",
        "AppType": "ABC"
    },
    {
        "AppTypeID": "dca6",
        "AppType": "MNO"
    },
    {
        "AppTypeID": "d8de",
        "AppType": "PQR"
    }
],
"CompTypes",
[
    {
        "CompTypeID": "0425",
        "CompType": "STU"
    },        
    {
        "CompTypeID": "0426",
        "CompType": "EDC"
    },
    {
        "CompTypeID": "0444",
        "CompType": "PLM"
    }
]
]

I am trying to deserialize the code, but not getting through. My Class,

     public class DAL
     {
           public DAL() { }
           public CompList CompList { get; set; }
     }

     public class CompList
     {
         public CompList()
         {
              AppTypes = new List<AppTypes>();
              CompType = new List<CompTypes>();                   
         }
         public List<AppTypes> AppTypes;
         public List<ComTypes> CompType;
     }
     public class AppTypes
     {
         public Guid AppTypeID { get; set; }
         public string AppType { get; set; }
     }

     public class CompTypes
     {
         public Guid CompTypeID { get; set; }
         public string CompType { get; set; }
     }

     public class JSONSerializer
     {
          public static T ConvertFromJSON<T>(String json)
          {
              JavaScriptSerializer serializer = new JavaScriptSerializer();
              return serializer.Deserialize<T>(json);
          }
     }

Controller Code:

    dynamic obj = JSONSerializer.ConvertFromJSON<DAL>(JsonData);

Not able to get where I am going wrong. Any help would be really appreciated.

7
  • 1
    Your JSON is really weird. In fact, it's not even valid. You will not be able to deserialize invalid JSON with a Deserialize call. You will need to use a JsonReader or something. Commented Mar 20, 2015 at 21:56
  • Also, I would recommend to use JSON.NET rather than the JavaScriptSerializer since it's WAAAYY more performant and more flexible. Commented Mar 20, 2015 at 22:17
  • Your lists for AppTypes and CompType aren't properties (no getter/settters). If the json was valid, it would be bound correctly by the DefaultModelBinder anyway so all this is unnecessary. Commented Mar 20, 2015 at 22:36
  • Thank you for the response, have updated the JSON. Is there anything I can implement now? Commented Mar 21, 2015 at 15:37
  • Your json is still not valid - {AppTypes: [ { "AppTypeID": "5136", "AppType": "ABC" }, {..} ], CompType: [ {..}, {..} ] }, and you don't have { get; set; } on AppTypes and CompType Commented Mar 22, 2015 at 1:37

1 Answer 1

3

The main problem here is that your JSON represents a top-level array containing either strings or nested arrays containing objects, but you are trying to deserialize this into a top-level object - not an array. Your class design is quite reasonable, but a serializer such as JavaScriptSerializer isn't really designed to completely restructure a data model in this way during deserialization. You may need to deserialize into a more literal representation of the JSON, then restructure the data with, say, Linq.

A secondary problem is that you are declaring your ID properties to be Guids, but the corresponding JSON properties (such as "AppTypeID": "5136") do not have enough digits to be Guids. JavaScriptSerializer expects a Guid to have 32 digits, optionally separated by hyphens, e.g.: "d70d7583-b2e6-4f6e-8d99-2022d3ca2b10" or "d70d7583b2e64f6e8d992022d3ca2b10".

Thus, if I change your Guid properties to strings:

public class AppTypes
{
    public string AppTypeID { get; set; }
    public string AppType { get; set; }
}

public class CompTypes
{
    public string CompTypeID { get; set; }
    public string CompType { get; set; }
}

Then I can deserialize and convert to a CompList as follows:

        var js = new JavaScriptSerializer();
        var array = js.Deserialize<List<object>>(JsonData); // Deserialize outer array
        var compList = new CompList
        {
            AppTypes = array
                .OfType<IEnumerable<object>>()          // Enumerate through nested arrays
                .SelectMany(o => o)                     // Enumerate through elements in nested arrays
                .OfType<IDictionary<string, object>>()  // Pick out those which are JSON objects (deserialized as dictionaries)
                .Where(d => d.ContainsKey("AppType"))   // Filter those that are AppTypes 
                .Select(d => js.ConvertToType<AppTypes>(d)) // Deserialize to the AppTypes class
                .ToList(),
            CompType = array
                .OfType<IEnumerable<object>>()
                .SelectMany(o => o)
                .OfType<IDictionary<string, object>>()
                .Where(d => d.ContainsKey("CompType"))
                .Select(d => js.ConvertToType<CompTypes>(d))
                .ToList(),
        };

FYI, your original code could deserialize JSON that looks like this into a CompList:

{
  "AppTypes": [
    {
      "AppTypeID": "5136",
      "AppType": "ABC"
    },
    {
      "AppTypeID": "dca6",
      "AppType": "MNO"
    },
    {
      "AppTypeID": "d8de",
      "AppType": "PQR"
    }
  ],
  "CompType": [
    {
      "CompTypeID": "0425",
      "CompType": "STU"
    },
    {
      "CompTypeID": "0426",
      "CompType": "EDC"
    },
    {
      "CompTypeID": "0444",
      "CompType": "PLM"
    }
  ]
}

Note that the outermost JSON is an object with two array-valued properties rather than an array of two strings and two arrays.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.