Deserialize Json with minus in property name [duplicate] - c#

This question already has answers here:
Parsing field name with a colon in JSON
(2 answers)
Closed 6 years ago.
I have a JSON return as below.
{
"id": 100,
"name": "employer 100",
"externalId": "100-100",
"networkId": 1000,
"address": {
"street-address": "1230 Main Street",
"locality": "Vancouver",
"postal-code": "V6B 5N2",
"region": "BC",
"country-name": "CA"
}
}
So I created class to deserialize the above json.
public class Employer
{
public int id { get; set; }
public string name { get; set; }
public string externalId { get; set; }
public int networkId { get; set; }
public Address address { get; set; }
}
public class Address
{
public string street_address { get; set; }
public string locality { get; set; }
public string postal_code { get; set; }
public string region { get; set; }
public string country_name { get; set; }
}
var response = _client.Execute(req);
return _jsonDeserializer.Deserialize <Employer> (response);
But I could not get street-address, postal-code and country-name from Json string. I think because of Json output keys contain ""-"" (As result of that I'm getting null).
So how could I resolve my issue ?

Use the DeserializeAs attribute on your properties:
[DeserializeAs(Name = "postal-code")]
public string postal_code { get; set; }
This allows you to set the same of the property in the json that maps to the property in your class, allowing the property to have a different name to the son.
https://github.com/restsharp/RestSharp/wiki/Deserialization

If you're using JSON.net, use attributes on your properties to specify the names that they should match up to:
public class Employer
{
public int id { get; set; }
public string name { get; set; }
public string externalId { get; set; }
public int networkId { get; set; }
public Address address { get; set; }
}
public class Address
{
[JsonProperty("street-address")]
public string street_address { get; set; }
public string locality { get; set; }
[JsonProperty("postal-code")]
public string postal_code { get; set; }
public string region { get; set; }
[JsonProperty("country-name")]
public string country_name { get; set; }
}

Related

Deserialize shodan data

I'm having problems deserializing the data I'm getting from Shodan. Below are the classes I got from json2csharp and I'm trying to create an array of the matches and loop through them. It seems like I have tried with everything except a working array by now. The data itself is matches as root with objects of them that contain location (with its own data etc). An except below that I cut out a bit.
This is my error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'Shodan.Match[]' because the type requ
ires a JSON array (e.g. [1,2,3]) to deserialize correctly.
var data = JsonConvert.DeserializeObject<Match[]>(allData);
{"matches": [{"product": "product", "hash": 0, "ip": 123123, "isp": "Verizon Internet Services"}], "total": 1}
public class Location
{
public string city { get; set; }
public string region_code { get; set; }
public object area_code { get; set; }
public double longitude { get; set; }
public string country_code3 { get; set; }
public double latitude { get; set; }
public string postal_code { get; set; }
public object dma_code { get; set; }
public string country_code { get; set; }
public string country_name { get; set; }
}
public class Options
{
}
public class Shodan
{
public string crawler { get; set; }
public string id { get; set; }
public string module { get; set; }
public Options options { get; set; }
}
public class Match
{
public int hash { get; set; }
public int ip { get; set; }
public string isp { get; set; }
public string transport { get; set; }
public string data { get; set; }
public string asn { get; set; }
public int port { get; set; }
public List<string> hostnames { get; set; }
public Location location { get; set; }
public DateTime timestamp { get; set; }
public List<string> domains { get; set; }
public string org { get; set; }
public object os { get; set; }
public Shodan _shodan { get; set; }
public string ip_str { get; set; }
public string product { get; set; }
}
public class RootObject
{
public List<Match> matches { get; set; }
public int total { get; set; }
}
You could create another class like
var allData =
{"matches": [{"product": "product", "hash": 0, "ip": 123123, "isp": "Verizon Internet Services"}], "total": 1}
public class MyMatches {
public Match[] matches {get; set;}
}
and then use that in the deserializer.
var data = JsonConvert.DeserializeObject<MyMatches>(allData);
This is if the JSON code sample you gave us is correct.
CORRECTION
Just saw the RootObject class.
Just use that.

Deserialized JSON String to C# Object gives the error "Cannot access static class in non-static context" when the object's methods are called

I'm trying to GET a JSON REST-api request, deserialize it using the Newtonsoft.Json package for .NET and access methods within the newly created object, but I keep getting an error that won't let me run my C# code in Visual Studio 2015.
For the following JSON string,
{
"pagination":
{
"per_page": 1,
"items": 28,
"page": 1,
"urls":
{
"last": "https://...",
"next": "https://..."
},
"pages": 28
},
"results":
[{
"style": ["House"],
"thumb": "https://...",
"format": ["File", "AAC", "Album"],
"country": "Unknown",
"barcode": ["id886037928"],
"uri": "/Porter-Robinson-Worlds/master/721049",
"community": {"have": 932, "want": 720},
"label": ["Astralwerks", "Sample Sized, LLC", "Astralwerks"],
"catno": "none",
"year": "2014",
"genre": ["Electronic"],
"title": "Porter Robinson - Worlds",
"resource_url": "https://...",
"type": "master",
"id": 721049
}]
}
I created the following C# object class:
public class Discogs
{
public class pagination
{
public int per_page { get; set; }
public int items { get; set; }
public int page { get; set; }
public class urls
{
public string last { get; set; }
public string next { get; set; }
}
public int pages { get; set; }
public class data
{
public string[] style { get; set; }
public string thumb { get; set; }
public string[] format { get; set; }
public string country { get; set; }
public string[] barcode { get; set; }
public string uri { get; set; }
public class community
{
public string have { get; set; }
public string want { get; set; }
}
public string[] label { get; set; }
public string catno { get; set; }
public string year { get; set; }
public string[] genre { get; set; }
public string title { get; set; }
public string resource_url { get; set; }
public string type { get; set; }
public string id { get; set; }
}
public class results
{
public data Results { get; set; }
}
}
}
In a private async void class, I've successfully fetched the GET request and stored it in the string, jsonstring. Now I try to run this code:
Discogs myUser = new Discogs();
myUser = JsonConvert.DeserializeObject<Discogs>(jsonstring);
int yr = myUser.pagination.data.year;
...but my project gets an error, An object reference is required for the non-static field, method, or property 'Discogs.pagination.data.year', cannot access non-static property 'year' in static context.
This does not make sense to me because I have no static classes or methods. I've searched for a solution but all similar problems seem to be able to access deserialized objects without any such error. Any help on accessing the methods in my Discogs object would be greatly appreciated.
The problem is that you are trying to use the class Pagination without instantiating the class. In order to use a non-static class (Pagination, Data, Community) you must first instantiate them like below
Pagination pag = new Pagination();
Your structure here is pretty odd. Normally classes would be in separate files or at least not nested such as you have here. You may want to rethink the way you've designed this program.
You are trying to get value from "myUser.pagination...", but in your example "pagination" is a class name not a property inside "Discogs" class, same as "data" inside "pagination" class
code with nested classes:
public class Discogs
{
public class Pagination
{
public int per_page { get; set; }
public int items { get; set; }
public int page { get; set; }
public class Urls
{
public string last { get; set; }
public string next { get; set; }
}
public Urls urls {get;set;}
public int pages { get; set; }
public class Data
{
public string[] style { get; set; }
public string thumb { get; set; }
public string[] format { get; set; }
public string country { get; set; }
public string[] barcode { get; set; }
public string uri { get; set; }
public class Community
{
public string have { get; set; }
public string want { get; set; }
}
public Community community { get; set; }
public string[] label { get; set; }
public string catno { get; set; }
public string year { get; set; }
public string[] genre { get; set; }
public string title { get; set; }
public string resource_url { get; set; }
public string type { get; set; }
public string id { get; set; }
}
public class Results
{
public Data Results { get; set; }
}
public Results result {get;set;}
}
public Pagination pagination {get;set}
}
code with i think a bit easy to understand:
public class Urls
{
public string last { get; set; }
public string next { get; set; }
}
public class Community
{
public string have { get; set; }
public string want { get; set; }
}
public class Data
{
public string[] style { get; set; }
public string thumb { get; set; }
public string[] format { get; set; }
public string country { get; set; }
public string[] barcode { get; set; }
public string uri { get; set; }
public string[] label { get; set; }
public string catno { get; set; }
public string year { get; set; }
public string[] genre { get; set; }
public string title { get; set; }
public string resource_url { get; set; }
public string type { get; set; }
public string id { get; set; }
public Community community { get; set; }
}
public class Results
{
public Data Results { get; set; }
}
public class Pagination
{
public int per_page { get; set; }
public int items { get; set; }
public int page { get; set; }
public int pages { get; set; }
public Urls urls {get;set;}
public Results result {get;set;}
}
public class Discogs
{
public Pagination pagination {get;set}
}

Deserializing this JSON response to C#

I have this specific JSON response that I am trying to deserialize without success. I am hoping someone can help me.
Here is the JSON response I get:
{
"num_locations": 1,
"locations": {
"98765": {
"street1": "123 Fake Street",
"street2": "",
"city": "Lawrence",
"state": "Kansas",
"postal_code": "66044",
"s_status": "20",
"system_state": "Off"
}
}
}
I used json2csharp http://json2csharp.com and got these recommended classes:
public class __invalid_type__98765
{
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
public class Locations
{
public __invalid_type__98765 __invalid_name__98765 { get; set; }
}
public class RootObject
{
public int num_locations { get; set; }
public Locations locations { get; set; }
}
But when I try to use it in my code:
var locationResponse = JsonConvert.DeserializeObject<RootObject>(response.Content);
What I get is (Watch):
locationResponse : {RestSharpConsoleApplication.Program.RootObject} : RestSharpConsoleApplication.Program.RootObject
locations : {RestSharpConsoleApplication.Program.Locations} : RestSharpConsoleApplication.Program.Locations
__invalid_name__98765 : null : RestSharpConsoleApplication.Program.__invalid_type__98765
num_locations : 1 : int
Obviously I am not creating (json2csharp) the right classes for the DeserializeObject, and sadly I have no control over the JSON response (vendor = SimpliSafe).
It is obvious the "98765" is meant to be a value (location number) but json2csharp makes it into this __invalid_type__98765 class and this is probably why it gets null.
Any idea how should the classes look for this particular JSON to be successfully deserialized?
Thanks!
Zachs
You should be able to do this with a dictionary:
public class MyData{
[JsonProperty("locations")]
public Dictionary<string, Location> Locations {get;set;}
}
public class Location
{
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
Do you have a non-Express version of Visual Studio? If so, copy the JSON to clipboard and then go to the Visual Studio menu: Edit >> Paste special >> Paste JSON as classes.
Using that gives:
public class Rootobject {
public int num_locations { get; set; }
public Locations locations { get; set; }
}
public class Locations {
public _98765 _98765 { get; set; }
}
public class _98765 {
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
That suggests your JSON structure is not quite right.
You can also specify the property name via an attribute to use to get around this:
public class RootObject
{
public int num_locations { get; set; }
public Locations locations { get; set; }
}
public class Locations
{
[JsonProperty("98765")]
public LocationInner Inner { get; set; }
}
public class LocationInner
{
public string street1 { get; set; }
public string street2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string s_status { get; set; }
public string system_state { get; set; }
}
...but it would really be better if the JSON were properly formatted such that the Locations was actually an array of location objects.

How do I convert a complex json object to CLR object with json.net?

sorry for a dumb question but I haven't found any solution for this.
Here is my JSON:
{
"Id": "1",
"Parent.Id": "1",
"Agent.Id": "1",
"Agent.Profile.FullName": "gena",
"Fee": "10.1200",
"FeeManagementDate": "29/11/2013",
"Contact.Name": "Genady",
"Contact.Telephone": "000000000",
"Contact.Email": "gena#email.com",
"AgreementUrl": "http://www.test.com/agreement"
}
Here is my object
public class ManagementDetailsViewModel : ViewModel<int> {
public ManagementDetailsViewModel() {
}
public string AgreementUrl { get; set; }
public HttpPostedFileBase AgreementFile { get; set; }
public decimal Fee { get; set; } // payment data
public DateTime? FeeDate { get; set; }
public string FeeManagementDate {
get { return FeeDate != null ? FeeDate.Value.ToString("dd/MM/yyyy") : DateTime.Now.ToString("dd/MM/yyyy"); }
set {
FeeDate = Convert.ToDateTime(value);
}
}
public BusinessViewModel Parent { get; set; }
public MemberViewModel Agent { get; set; }
public Contact Contact { get; set; }
}
How do I convert the json string to object (with inner objects)?
Json.Net needs some help because your json object contain propery names, which is not valid in c# like(Agent.Id)
var obj = JsonConvert.DeserializeObject<MyObj>(json);
How do I convert the json string to object (with inner objects)?
Since your json is flat(not containing sub objects) you have to post process your deserialized object if you want to use it that way/
public class MyObj
{
public string Id { get; set; }
[JsonProperty("Parent.Id")]
public string ParentId { get; set; }
[JsonProperty("Agent.Id")]
public string AgentId { get; set; }
[JsonProperty("Agent.Profile.FullName")]
public string ProfileFullName { get; set; }
public string Fee { get; set; }
public string FeeManagementDate { get; set; }
[JsonProperty("Contact.Name")]
public string ContactName { get; set; }
[JsonProperty("Contact.Telephone")]
public string ContactTelephone { get; set; }
[JsonProperty("Contact.Email")]
public string ContactEmail { get; set; }
public string AgreementUrl { get; set; }
}

JSONConvert.DeserializeObject not handling child array with unnamed array items

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.

Categories