I currently have JSON coming in as follows:
{"36879":[{"min_qty":1,"discount_type":"%","csp_price":10}],"57950":[{"min_qty":1,"discount_type":"flat","csp_price":650}]}
This contains a list of the following records
ProductId
MinQty
DiscountType
Price
I need to deserialize this into the following model:
public class CustomerSpecificPricing
{
string productId { get; set; }
public virtual List<CustomerSpecificPricingDetail> CustomerSpecificPricingDetails { get; set; }
}
public class CustomerSpecificPricingDetail
{
public string min_qty { get; set; }
public string discount_type { get; set; }
public string csp_price { get; set; }
}
The problem is that the "productId" of each record is missing the key name.
If I run my JSON through J2C, I get the following:
public class 36879 {
public int min_qty { get; set; }
public string discount_type { get; set; }
public int csp_price { get; set; }
}
public class 57950 {
public int min_qty { get; set; }
public string discount_type { get; set; }
public int csp_price { get; set; }
}
public class Root {
public List<_36879> _36879 { get; set; }
public List<_57950> _57950 { get; set; }
}
Which is obviously incorrect.
How would I deserialize my object correctly?
You would need to deserialize it into a dictionary first and then map it into the format you require after. Something like this should work:
var dict = JsonConvert.DeserializeObject<Dictionary<string, IEnumerable<CustomerSpecificPricingDetail>>>();
var result = dict.Select(kvp => new CustomerSpecificPricing { ProductId = Int32.Parse(kvp.Key), CustomerSpecificPricingDetails = kvp.Value });
Id also recommend you follow the conventional standards of naming. In this case properties in classes should be PascalCase,
e.g. your classes now become:
public class CustomerSpecificPricing
{
[JsonProperty("productId ")]
public string ProductId { get; set; }
public virtual List<CustomerSpecificPricingDetail> CustomerSpecificPricingDetails { get; set; }
}
and
public class CustomerSpecificPricingDetail
{
[JsonProperty("min_qty")]
public string MinQty { get; set; }
[JsonProperty("discount_type ")]
public string DiscountType { get; set; }
[JsonProperty("csp_price ")]
public string CspPrice { get; set; }
}
I'm attempting to deserialize the following json:
{"PatientNameID":{"ID":514,"Name":{"First":"Laura","Middle":"X","Last":"Coelho","Suffix":"","Full":"Laura X Coelho","Preferred":""}},"PatientNumber":"254","ChartNumber":"254","Gender":{"LookupType":"Gender","Code":"F","Description":"Female","Order":1,"Active":true,"AlternateCodes":null},"DOB":"4/9/1953","PhoneNumber":"3521029496","SSN":"*****0161"}
This is the class and subclasses into which I'm trying to deserialize the above JSON:
public class PatientList3
{
public Pat PatientNameID { get; set; }
public string PatientNumber { get; set; }
public string ChartNumber { get; set; }
public Gender2 Gender { get; set; }
public string DOB { get; set; }
public string PhoneNumber { get; set; }
public string SSN { get; set; }
}
public class Pat
{
public int ID { get; set; }
public PtName Name { get; set; }
}
public class PtName
{
public string First { get; set; }
public string Middle { get; set; }
public string Last { get; set; }
public string Suffix { get; set; }
public string Full { get; set; }
public string Preferred { get; set; }
}
public class Gender2
{
string LookupType { get; set; }
string Code { get; set; }
string Description { get; set; }
int Order { get; set; }
bool Active { get; set; }
List<AlternateCodes> AlternateCodes { get; set; }
}
public class AlternateCodes
{
string Code { get; set; }
string Description { get; set; }
string CodeSystem { get; set; }
string CodeSystemName { get; set; }
}
Everything goes well when I deserialize it except all of the values in the Gender2 class are null.
I've referred to the following two posts for answers but nothing seems to be doing to trick.
JsonConvert.DeserializeObject<T>(JsonString) returning all Properties<T> as Null
DeSerializing JSON returns null C#
Fix the properties on Gender2 & AlternateCodes they are not public! The deserializer will not be able to find your any of your properties so that is probably the reason this fails to populate.
The problem is with access modifiers of properties Gender2 and AlternateCodes class, default access modifiers for properties is private. You should change it to:
public class Gender2
{
public string LookupType { get; set; }
public string Code { get; set; }
public string Description { get; set; }
public int Order { get; set; }
public bool Active { get; set; }
public List<AlternateCodes> AlternateCodes { get; set; }
}
public class AlternateCodes
{
public string Code { get; set; }
public string Description { get; set; }
public string CodeSystem { get; set; }
public string CodeSystemName { get; set; }
}
After setting properties to public it deserializes successfully:
So I created a class using json2csharp
public class ResponseType
{
public class Query
{
public string q { get; set; }
public object sku { get; set; }
public int limit { get; set; }
public object reference { get; set; }
public object mpn_or_sku { get; set; }
public string mpn { get; set; }
public object brand { get; set; }
public string __class__ { get; set; }
public int start { get; set; }
public object seller { get; set; }
}
public class Request
{
public bool exact_only { get; set; }
public string __class__ { get; set; }
public List<Query> queries { get; set; }
}
public class Seller
{
public string display_flag { get; set; }
public bool has_ecommerce { get; set; }
public string name { get; set; }
public string __class__ { get; set; }
public string homepage_url { get; set; }
public string id { get; set; }
public string uid { get; set; }
}
public class Prices
{
public List<List<object>> USD { get; set; }
public List<List<object>> JPY { get; set; }
public List<List<object>> CNY { get; set; }
}
public class Offer
{
public string sku { get; set; }
public string packaging { get; set; }
public string on_order_eta { get; set; }
public string last_updated { get; set; }
public int? order_multiple { get; set; }
public int in_stock_quantity { get; set; }
public string eligible_region { get; set; }
public int? moq { get; set; }
public int? on_order_quantity { get; set; }
public object octopart_rfq_url { get; set; }
public string __class__ { get; set; }
public Seller seller { get; set; }
public string product_url { get; set; }
public object factory_order_multiple { get; set; }
public string _naive_id { get; set; }
public int? factory_lead_days { get; set; }
public Prices prices { get; set; }
public bool is_authorized { get; set; }
public bool is_realtime { get; set; }
}
public class Brand
{
public string homepage_url { get; set; }
public string __class__ { get; set; }
public string name { get; set; }
public string uid { get; set; }
}
public class Manufacturer
{
public string homepage_url { get; set; }
public string __class__ { get; set; }
public string name { get; set; }
public string uid { get; set; }
}
public class Item
{
public List<Offer> offers { get; set; }
public string uid { get; set; }
public string mpn { get; set; }
public List<object> redirected_uids { get; set; }
public Brand brand { get; set; }
public string octopart_url { get; set; }
public string __class__ { get; set; }
public Manufacturer manufacturer { get; set; }
}
public class Result
{
public List<Item> items { get; set; }
public int hits { get; set; }
public string __class__ { get; set; }
public object reference { get; set; }
public object error { get; set; }
}
public class RootObject
{
public int msec { get; set; }
public Request request { get; set; }
public string __class__ { get; set; }
public List<Result> results { get; set; }
}
}
The problem is at design-time, when I declare a variable with the type of my class:
ResponseType Response = new ResponseType();
Intellisense does not allow me to access the subclasses RootObject.results list. It only shows Equals, GetHashCode, GetType and ToString. I am assuming I did something wrong in my class declaration.
Thank you in advance!
Edit -- I am fairly new to C Sharp. I am trying to parse a response from a REST API. I took the JSON provided by the Rest API and converted it using json2csharp into a class. My intent was to do something like this
Within a function return:
public ResponseType ExecuteSearch(String PartNumber)
{
~ ALL CODE FOR GENERATING req
// Perform the search and obtain results
var data = client.Execute(req).Content;
JSON = data;
return JsonConvert.DeserializeObject<ResponseType>(data);
}
Then being able to access the response as an object outside of the function
Edit 2:
I figured out what I did. Instead of nesting everything within the ResponseType I should have simply renamed RootObject to ResponseType.
Intellisense does not allow me to access the subclasses RootObject.results list
it is because the property results is not static and you try to acces it this way. A static property is accessed via ClassName.PropertyName. For more information on static variables check the link.
It only shows Equals, GetHashCode, GetType and ToString
This is the basic set of methods that every object in C# inherits from the class object. This is why you can see it.
Intellisense will allow you to do this:
ResponseType.RootObject ro = new ResponseType.RootObject();
ro.results.First();
because you will need an Instance of that class to acces the property results.
I am assuming I did something wrong in my class declaration.
It depends. Basically if the compiler does not complain then you declared your classes as supposed to be. But the declaration of the properties commands you to access them in a specific way. So if you still want to access results with RootObject.results you need to make it static:
public class RootObject
{
public static List<Result> results { get; set; }
}
But note that this list will exist only once! and is not individual to each instance of RootObject! Since you have embedded classes you need to call it like this:
ResponseType.RootObject.results.WhatEver();
EDIT
I guess you would like to get the Object of type RootObject inside the Object of type ResponseType. If I am right then it is not necessary to declare the classes inside ResponseType but you have to declare variables of each type inside it like:
public class ResponseType
{
public RootObject MyRootObject{ get; set; }
}
public class RootObject
{
public int msec { get; set; }
public Request request { get; set; }
public string __class__ { get; set; }
public List<Result> results { get; set; }
}
Now you will be able to access the results variable inside the ResponseType object:
ResponseType rt = new ResponseType();
rt.MyRootObject.results.WhatEver();
For more information on how to deserialize JSON to classes please read the Deserialize JSON to C# Classes post
1) Object with ResponseType class isn't contain any fields(event static one).
2) You declare ResponseType object, but results is field of RootObject object.
So if you want to work with results you should do something like this:
ResponseType.RootObject rootObject = new ResponseType.RootObject();
rootObject.results.DoWork();
Below is what I think you are trying to do. I would only use it in this form if this is some kind of Data Transfer Object (DTO) because otherwise it is pretty bad practice for a class that would be used in code (mostly because of the public getters and setters on all of the fields and the field names matching the class name), but it does show your main mistake and that is that classes need to be defined outside of your main class and if you need that type of class in your top level class you need to define a public field to access it.
public class ResponseType
{
public Query Query { get; set; }
public Request Request { get; set; }
public Seller Seller { get; set; }
public Prices Prices { get; set; }
public Offer Offer { get; set; }
public Brand Brand { get; set; }
public Manufacturer Manufacturer { get; set; }
public Item Item { get; set; }
public Result Result { get; set; }
public RootObject RootObject { get; set; }
}
public class Query
{
public string q { get; set; }
public object sku { get; set; }
public int limit { get; set; }
public object reference { get; set; }
public object mpn_or_sku { get; set; }
public string mpn { get; set; }
public object brand { get; set; }
public string __class__ { get; set; }
public int start { get; set; }
public object seller { get; set; }
}
public class Request
{
public bool exact_only { get; set; }
public string __class__ { get; set; }
public List<Query> queries { get; set; }
}
public class Seller
{
public string display_flag { get; set; }
public bool has_ecommerce { get; set; }
public string name { get; set; }
public string __class__ { get; set; }
public string homepage_url { get; set; }
public string id { get; set; }
public string uid { get; set; }
}
public class Prices
{
public List<List<object>> USD { get; set; }
public List<List<object>> JPY { get; set; }
public List<List<object>> CNY { get; set; }
}
public class Offer
{
public string sku { get; set; }
public string packaging { get; set; }
public string on_order_eta { get; set; }
public string last_updated { get; set; }
public int? order_multiple { get; set; }
public int in_stock_quantity { get; set; }
public string eligible_region { get; set; }
public int? moq { get; set; }
public int? on_order_quantity { get; set; }
public object octopart_rfq_url { get; set; }
public string __class__ { get; set; }
public Seller seller { get; set; }
public string product_url { get; set; }
public object factory_order_multiple { get; set; }
public string _naive_id { get; set; }
public int? factory_lead_days { get; set; }
public Prices prices { get; set; }
public bool is_authorized { get; set; }
public bool is_realtime { get; set; }
}
public class Brand
{
public string homepage_url { get; set; }
public string __class__ { get; set; }
public string name { get; set; }
public string uid { get; set; }
}
public class Manufacturer
{
public string homepage_url { get; set; }
public string __class__ { get; set; }
public string name { get; set; }
public string uid { get; set; }
}
public class Item
{
public List<Offer> offers { get; set; }
public string uid { get; set; }
public string mpn { get; set; }
public List<object> redirected_uids { get; set; }
public Brand brand { get; set; }
public string octopart_url { get; set; }
public string __class__ { get; set; }
public Manufacturer manufacturer { get; set; }
}
public class Result
{
public List<Item> items { get; set; }
public int hits { get; set; }
public string __class__ { get; set; }
public object reference { get; set; }
public object error { get; set; }
}
public class RootObject
{
public int msec { get; set; }
public Request request { get; set; }
public string __class__ { get; set; }
public List<Result> results { get; set; }
}
I am getting Json data from a web server, but when I try to deserialize it to objects, I am not getting any data. The Json string looks like this:
{"success":true,"data":[{"Id":6,"CustomerGuid":"70b390d8-82d5-4bba-aa68-fc8268a1b1ff","UserName":"victoria_victoria#nopCommerce.com","Email":"victoria_victoria#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472393)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472393)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":5,"CustomerGuid":"eb9e6f24-f362-4c10-942a-366e2919dc11","UserName":"brenda_lindgren#nopCommerce.com","Email":"brenda_lindgren#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472363)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472363)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":4,"CustomerGuid":"9f46dbae-6942-410c-90b8-9b38a0890064","UserName":"james_pan#nopCommerce.com","Email":"james_pan#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472317)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472317)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":3,"CustomerGuid":"6277386b-13ee-427b-9cfe-4ebfa487c340","UserName":"arthur_holmes#nopCommerce.com","Email":"arthur_holmes#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472253)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472253)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":2,"CustomerGuid":"241f45f1-b38c-4e22-8c5a-743fa3276620","UserName":"steve_gates#nopCommerce.com","Email":"steve_gates#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472207)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472207)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":1,"CustomerGuid":"a940dc03-5f52-47d2-9391-8597b3b31cf2","UserName":"tony#lakesideos.com","Email":"tony#lakesideos.com","CustomerRoles":[{"Id":1,"Name":"Administrators","SystemName":"Administrators"},{"Id":2,"Name":"Forum Moderators","SystemName":"ForumModerators"},{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":true,"Active":true,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":"71.185.255.7","CreatedOnUtc":"\/Date(1472933470783)\/","LastLoginDateUtc":"\/Date(1477522483903)\/","LastActivityDateUtc":"\/Date(1477523996553)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[{"Id":1,"StoreId":1,"ShoppingCartTypeId":1,"CustomerId":1,"ProductId":18,"AttributesXml":null,"CustomerEnteredPrice":0.0000,"Quantity":1,"CreatedOnUtc":"\/Date(1473801903447)\/","UpdatedOnUtc":"\/Date(1473803336207)\/","IsFreeShipping":false,"IsShipEnabled":true,"AdditionalShippingCharge":0.0000,"IsTaxExempt":false}]}]}
I created these classes from the recommendation given in this link:
recommendation
I used this to create the classes: json2csharp
Response class:
class Response
{
bool success;
IList<Customer> data;
}
Customer class:
class Customer
{
public int Id { get; set; }
public string CustomerGuid { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public List<CustomerRole> CustomerRoles { get; set; }
public object AdminComment { get; set; }
public bool IsTaxExempt { get; set; }
public int AffiliateId { get; set; }
public int VendorId { get; set; }
public bool HasShoppingCartItems { get; set; }
public bool Active { get; set; }
public bool Deleted { get; set; }
public bool IsSystemAccount { get; set; }
public object SystemName { get; set; }
public string LastIpAddress { get; set; }
public DateTime CreatedOnUtc { get; set; }
public DateTime? LastLoginDateUtc { get; set; }
public DateTime LastActivityDateUtc { get; set; }
public List<object> ExternalAuthenticationRecords { get; set; }
public List<object> ShoppingCartItems { get; set; }
}
CustomerRole class:
class CustomerRole
{
public int Id { get; set; }
public string Name { get; set; }
public string SystemName { get; set; }
}
ExternalAuthenticationRecord class:
class ExternalAuthenticationRecord
{
public int Id { get; set; }
public int CustomerId { get; set; }
public string Email { get; set; }
public object ExternalIdentifier { get; set; }
public object ExternalDisplayIdentifier { get; set; }
public object OAuthToken { get; set; }
public object OAuthAccessToken { get; set; }
public string ProviderSystemName { get; set; }
}
ShoppingCartItem class:
class ShoppingCartItem
{
public int Id { get; set; }
public int StoreId { get; set; }
public int ShoppingCartTypeId { get; set; }
public int CustomerId { get; set; }
public int ProductId { get; set; }
public object AttributesXml { get; set; }
public double CustomerEnteredPrice { get; set; }
public int Quantity { get; set; }
public DateTime CreatedOnUtc { get; set; }
public DateTime UpdatedOnUtc { get; set; }
public bool IsFreeShipping { get; set; }
public bool IsShipEnabled { get; set; }
public double AdditionalShippingCharge { get; set; }
public bool IsTaxExempt { get; set; }
}
I am using this statement to deserialzie the Json string: Response res = (Response)JsonConvert.DeserializeObject(customerJson, (typeof(Response)));
When I stop it in the debugger, it shows "res" as data: null and success: false.
I am not getting any errors. It is just not giving me the data from the Json string.
Any help that anybody can provide to figure out why I'm not getting the data I want in "res", would be gratefully appreciated.
Thanks,
Tony
The problem is related to the accessibility level in your Response class. By default the fields, property and method are private so JsonConvert is not able to fill the properties.
Change the class as follow:
class Response
{
public bool success {get; set;}
public IList<Customer> data {get; set;}
}
And it wil works.
Another improvement is related to the JsonConvert use. To avoid the explicit cast use this type conversion: JsonConvert.DeserializeObject<T>(string) where T will be Response
I have the following JSON object coming to me from a web service
{
"room":{
"name":"Thunderdome",
"created_at":"2012/04/15 00:36:27 +0000",
"id":xxxxxxx,
"users":[
{
"type":"Member",
"avatar_url":"url",
"created_at":"2012/02/27 14:11:57 +0000",
"id":1139474,
"email_address":"xxx#xxxxxxx.com",
"admin":false,
"name":"xxxx xxxxx"
},
{
"type":"Member",
etc
I'm using the following line to deserialize:
var room = JsonConvert.DeserializeObject<SingleRoom>(text);
And the following mapping classes
public class SingleRoom
{
public Room Room { get; set; }
}
[DataContract]
public class Room
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
public string Image {
get { return "Assets/campfire.png"; }
}
[DataMember]
public string Topic { get; set; }
[DataMember(Name ="membership_limit")]
public int MembershipLimit { get; set; }
[DataMember]
public bool Full { get; set; }
[DataMember]
public bool Locked { get; set; }
[DataMember(Name = "open_to_guests")]
public bool OpenToGuests { get; set; }
[DataMember(Name = "updated_at")]
public DateTime UpdatedAt { get; set; }
[DataMember(Name = "created_at")]
public DateTime CreatedAt { get; set; }
[DataMember(Name = "active_token_value")]
public string ActiveTokenValue { get; set; }
[DataMember(Name = "Users")]
public List<User> Users { get; set; }
}
[DataContract]
public class User
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember(Name = "email_address")]
public string EmailAddress { get; set; }
[DataMember]
public bool Admin { get; set; }
[DataMember]
public DateTime CreatedAt { get; set; }
[DataMember]
public string Type { get; set; }
[DataMember(Name = "avatar_url")]
public string AvatarUrl { get; set; }
}
The 'Room' object deserializes correctly but the Users property on the Room is always null. I know that a null result is the result of a JSON.NET serialization that couldn't find the matching property. However, I think I have it right? List should match to user. I know the array object users in the JSON doesn't have named children, is that the issue? If so, how do I solve it?
Thanks!
This works.... You can rename them (or use JsonProperty attribute) to use c# style property names
(BTW: Json.Net doesn't require DataMember, DataContract attributes)
var obj = JsonConvert.DeserializeObject<SingleRoom>(json)
public class User
{
public string type { get; set; }
public string avatar_url { get; set; }
public string email_address { get; set; }
public bool admin { get; set; }
public string name { get; set; }
public string created_at { get; set; }
public int id { get; set; }
}
public class Room
{
public string topic { get; set; }
public int membership_limit { get; set; }
public bool locked { get; set; }
public string name { get; set; }
public List<User> users { get; set; }
public bool full { get; set; }
public bool open_to_guests { get; set; }
public string updated_at { get; set; }
public string created_at { get; set; }
public int id { get; set; }
}
public class SingleRoom
{
public Room room { get; set; }
}
PS: You may find that site useful http://json2csharp.com/ .
In my case, I had missing to add the "public" key for the child property.