25818

How to parse JSON received in MVC Controller

I have a JSON file that is being sent to an MVC controller via a POST request from the client side. Since there isn't a direct way to store JSON in C#, I'm trying to create models to store the data. Here is the structure of the JSON:

{ "SubscriptionsType1": { "Obj1": { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "True" }, "Obj2": { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "True" }, "Obj3": { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "True" } }, "SubscriptionsType2": { "Obj1": { "Value1": "3667635", "Value2": "34563456", "Value3": "234545", "Value4": "False" }, "Obj2": { "Value1": "97865", "Value2": "356356", "Value3": "665757445", "Value4": "True" }, "Obj3": { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "False" } }, //etc.. }

The models are the following:

public class RootObject { public IEnumerable<SubscriptionObj> Subscriptions { get; set; } } public class Subscriptions { IEnumerable<SubscriptionObj> objs; } public class SubscriptionObj { public Int64 Value1 {get;set;} public Int64 Value2 {get;set;} public Int64 Value3 {get;set;} public Boolean Value4 {get;set;} }

For some reason, if I create the model classes with this structure, the Root Object is still null after the it is passed the JSON object from the controller. However, when I explicitly create attributes to store each value of the JSON object, it works. Since the JSON object doesn't have a fixed number of elements, I need a way to dynamically store each attribute. <strong>How can this be done?</strong>

Answer1:

Because of the varying key in the root object and subscriptions, you should use a dictionary.

public class RootObject : Dictionary<string, Subscriptions> { } public class Subscriptions : Dictionary<string, SubscriptionObj> { } public class SubscriptionObj { public Int64 Value1 {get;set;} public Int64 Value2 {get;set;} public Int64 Value3 {get;set;} public Boolean Value4 {get;set;} }

The above would serialize to the JSON in the OP but you loose the strongly typed keys/property names

Answer2:

The json corresponding to your c# classes should use arrays, something like

{ "Subscriptions": [ { "Obj": [ { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "True" }, { "Value1": "3454234", ... }, { "Value1": "3454234", ... } ] }, //end of Subscription 1 { "Obj": [ { "Value1": "3454234", ... }, { "Value1": "3454234", ... }, { "Value1": "3454234", ... } ] } //end of Subscription 2 ] }

The c# classes corresponding to your json with no arrays will look something like:

public class ObjType { public string Value1 { get; set; } public string Value2 { get; set; } public string Value3 { get; set; } public string Value4 { get; set; } } public class SubscriptionsType { public ObjType Obj1 { get; set; } public ObjType Obj2 { get; set; } public ObjType Obj3 { get; set; } } public class RootObject { public SubscriptionsType SubscriptionsType1 { get; set; } public SubscriptionsType SubscriptionsType2 { get; set; } }

Answer3:

for that datastructure i would deserialize the object to dynamic. then you can check if there is "SubscriptionsType1" or "SubscriptionsType2", ...

with the dynamic i would create the model classes and fill them in a self brewed deserialization method/class.

the design of the model is not serialization friendly, can you change the json that you will get by changing the contract with the caller?

if so here is my suggestion:

{ "Subscriptions": [ { "Objects": [{ "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "True" }, { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "True" }, { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "True" } ] }, { "Objects": [ { "Value1": "3667635", "Value2": "34563456", "Value3": "234545", "Value4": "False" }, { "Value1": "97865", "Value2": "356356", "Value3": "665757445", "Value4": "True" }, { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "False" }] }, //etc.. ] }

your model would change to:

public class RootObject { public Subscriptions SubscriptionCollection { get; set; } } public class Subscriptions { IEnumerable<SubscriptionObj> objs; } public class SubscriptionObj { public Int64 Value1 {get;set;} public Int64 Value2 {get;set;} public Int64 Value3 {get;set;} public Boolean Value4 {get;set;} }

is that what you are trying to get?

Answer4:

From your JSON file, we can extract the model classes below:

public class RootModel{ public SubscriptionTypeModel SubscriptionsType1 { get; set; } public SubscriptionTypeModel SubscriptionsType2 { get; set; } //etc... } public class SubscriptionTypeModel { public ObjectModel Obj1 { get; set; } public ObjectModel Obj2 { get; set; } public ObjectModel Obj3 { get; set; } } public class ObjectModel { public string Value1 { get; set; } public string Value2 { get; set; } public string Value3 { get; set; } public bool Value4 { get; set; } }

If the list of subscriptions is dynamic, then you should change your JSON file to look like the one below:

[ {"Subscriptions": [ { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "True" }, { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "True" }, { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "True" } ]}, { "Subscriptions":[ { "Value1": "3667635", "Value2": "34563456", "Value3": "234545", "Value4": "False" }, { "Value1": "97865", "Value2": "356356", "Value3": "665757445", "Value4": "True" }, { "Value1": "3454234", "Value2": "345643564", "Value3": "665445", "Value4": "False" } ]} ]

Recommend

  • How to change current directory in Make
  • Deserialize a json field with different data types without using Newtonsoft json but with System.Web
  • Pandas remap to range in column
  • BigQuery not dealing with timestamp in millisecond with partition column
  • WMQ Pub/Sub Topic to Queue bridge
  • Invalid module format
  • Azure file Storage SMB slow to list files in directory
  • ndk-build error.opencv2/core/core.hpp: No such file or directory
  • How to implement 'category' based newsletter
  • Validating embedded document in Mongoid based on embedded attribute
  • Create list of objects from Json object with objects in xamarin for Android
  • Deserializing this JSON response to C#
  • How to detect if user cancel auto-renewable subscriptions during the free trial period?
  • Multiplying column elements of sparse Matrix
  • Using a canvas object in a thread to do simple animations - Java
  • How can I extract results of aggregate queries in slick?
  • OOP Javascript - Is “get property” method necessary?
  • ilmerge with a PFX file
  • Spring Data JPA custom method causing PropertyReferenceException
  • Can I display google adwords (AdView) in javafx on android
  • PHP - How to update data to MySQL when click a radio button
  • Validaiting emails with Net.Mail MailAddress
  • sending/ receiving email in Java
  • VB.net deserialize, JSON Conversion from type 'Dictionary(Of String,Object)' to type '
  • Cannot Parse HTML Data Using Android / JSOUP
  • How to set the response of a form post action to a iframe source?
  • JTable with a ScrollPane misbehaving
  • Java static initializers and reflection
  • Change div Background jquery
  • Qt: Run a script BEFORE make
  • Bitwise OR returns boolean when one of operands is nil
  • unknown Exception android
  • reshape alternating columns in less time and using less memory
  • Observable and ngFor in Angular 2
  • How to Embed XSL into XML
  • failed to connect to specific WiFi in android programmatically
  • UserPrincipal.Current returns apppool on IIS
  • Unable to use reactive element in my shiny app
  • Conditional In-Line CSS for IE and Others?
  • How can I use threading to 'tick' a timer to be accessed by other threads?