Model to match this JSON for deserialization, field names with dashes - c#

I am trying to create a model that would match the JSON.NET deserealization of this JSON structure:
First item...
{
"190374": {
"vid": 190374,
"canonical-vid": 190374,
"portal-id": 62515,
"is-contact": true,
"profile-token": "AO_T-mN1n0Mbol1q9X9UeCtRwUE1G2GFUt0VVxCzpxUF1LJ8L3i75x9NmhIiS0K9UQkx19bShhlUwlIujY4pSXAFPEfDG-k9n8BkbftPw6Y5oM3eU5Dc_Mm-5YNJTXiWyeVSQJAN_-Xo",
"profile-url": "https://app.hubspot.com/contacts/62515/lists/public/contact/_AO_T-mN1n0Mbol1q9X9UeCtRwUE1G2GFUt0VVxCzpxUF1LJ8L3i75x9NmhIiS0K9UQkx19bShhlUwlIujY4pSXAFPEfDG-k9n8BkbftPw6Y5oM3eU5Dc_Mm-5YNJTXiWyeVSQJAN_-Xo/",
"properties": {
"phone": {
"value": "null"
},
"hs_social_linkedin_clicks": {
"value": "0"
},
"hs_social_num_broadcast_clicks": {
"value": "0"
},
"hs_social_facebook_clicks": {
"value": "0"
},
"state": {
"value": "MA"
},
"createdate": {
"value": "1380897795295"
},
"hs_analytics_revenue": {
"value": "0.0"
},
"lastname": {
"value": "Mott"
},
"company": {
"value": "HubSpot"
}
},
"form-submissions": [],
"identity-profiles": []
},
"form-submissions": [],
"identity-profiles": []
},
**next similar entry**
Then I try to bind with List of this:
public class HubSpotEmailRqst
{
public int vid { get; set; }
public int canonical-vid { get; set; }
public int portal-id { get; set; }
public bool is-contact { get; set; }
public String profile-token { get; set; }
public String profile-url { get; set; }
public Dictionary<string, string> properties { get; set; }
public Dictionary<string,string> form-submissions { get; set; }
public Dictionary<string,string> identity-profiles { get; set; }
}
I am not sure this will bind either, but I cannot get past the fact we cannot have hyphen in the field names, how can I get around this?

There're two ways to use properties with hyphens:
Name properties according to C# rules, but decorate them with [JsonProperty("property-name")] attribute.
Use custom contract resolver which modifies property names. For example, if all properties in JSON are named consistently, you can use regex to change PascalCase C# property names to lower-case JSON property names. See CamelCasePropertyNamesContractResolver from Json.NET for example implementation.

If I'm understanding the question correctly, you are upset that you can't use a hyphen in a field name in a C# program? Why not use CamelCase to identify the fields? Instead of is-contact use 'isContact'. Instead of canonical-vid. use canonicalVid. Sure, the names may look different, but to the programmer the meaning should be clear.

Related

Unusual JSON construct

I am supposed to read the following JSON response:
ValueFilters:[
{field:"amount", comparitor:"GREATER", "value": 0},
{operator:"AND"},
{field:"id", comparitor:"LESS", "value": 5}]
If it did not contain 'operator' object then I would not have any problem, but with it how do I construct the equivalent C# object?
First off, your example, the JSON is not valid JSON. To make it valid, one must add quotes to each of the property names such as field to "field". Once that is done the Json can be parsed:
{
"ValueFilters": [
{
"field": "amount",
"comparitor": "GREATER",
"value": 0
},
{
"operator": "AND"
},
{
"field": "id",
"comparitor": "LESS",
"value": 5
}
]
}
By taking that valid Json above it can be serialized into these C# classes:
public class Filters
{
public List<ValueFilter> ValueFilters { get; set; }
}
public class ValueFilter
{
[JsonPropertyName("operator")] // Handle the C# `operator` keyword.
public string Operator { get; set; }
public string field { get; set; }
public string comparitor { get; set; } // Misspell -> comparator
public int value { get; set; }
}
Using your favorite derializer would look like this, .Net 5 System.Text.Json shown:
var filter = JsonSerializer.Deserialize<Filters>(data);
Which when deserialized you have 3 ValueFilter items. By checking whether the Operator property is not null or not, the future code knows what to do with the data.
Operator
field
comparitor
value
null
amount
GREATER
0
AND
null
null
0
null
id
LESS
5

Json DeserializeObject into class with dynamic property

I'm trying to convert a string of JSON data into a C# class object. However I'm having an issue with a small part of the JSON which is dynamic in nature.
The part of the JSON is below:
"contact": [{
"comment": null,
"type": {
"id": "cell",
"name": "Example name"
},
"preferred": true,
"value": {
"country": "7",
"formatted": "+7 (702) 344-3423-3",
"number": "3498908",
"city": "702"
}
},
{
"type": {
"id": "email",
"name": "Email example"
},
"preferred": false,
"value": "name#mail.com"
}]
C# classes
public class Value
{
public string country { get; set; }
public string formatted { get; set; }
public string number { get; set; }
public string city { get; set; }
}
public class Type
{
public string id { get; set; }
public string name { get; set; }
}
public class Contact
{
public string comment { get; set; }
public Type type { get; set; }
public bool preferred { get; set; }
public string value { get; set; }
}
C# Code
Contact contact = JsonConvert.DeserializeObject<Contact>(result);
The format of "value" changes depending on the contact information. Is it possible to map value both as a string and also class Value.
Thanks for any help that can be provided.
You can literally just use dynamic, i.e.
public dynamic value { get; set; }
If it looks like an object, it will be materialized as a JObject, which can be used via the dynamic API, so .value.country will work, etc. If it looks like an integer, bool or string: it will be materialized as such. Arrays will also be handled suitably. So: you can check whether .value is string, etc. Note that this won't use your Value type, and doing so is more complex, but: meh; you get the data. You can always switch that out manually.
It will also behave like this if you use object instead of dynamic, but then it is harder to access the inner properties.
Try
Contact contact = JsonConvert.DeserializeObject<Contact>(result[0]);
As you can see in the JSON, it's
"contact": [
Indicating an array, currently you're just passing the entire array
Unless you're sure that the JSON comes always with the same structure, the best is to use a dynamic variable instead of deserialize it into a class.
If you like to work with classes you can always build your own on runtime using reflection. But that's like killing a fly with a cannon and you're probably won't need it, so just use a dynamic variable instead, it's the best to work with JSON strings.

How to mapping a multiple type javascript array to C# array

I use asp.net MVC model binding to accept the parameters for ajax.
I have an object, it's data structure like this:
{
"conditions": [
{
"field": "",
"opreator": "",
"value": ""
},[{
"field": "",
"opreator": "",
"value": ""
},
{
"field": "",
"opreator": "",
"value": ""
}]
],
"name": "query",
}
C# array can't has different types. (the property conditions is an arrray that has object and array).
So I defined an object array.
public class QueryVM
{
public class condition
{
public string field { get; set; }
public string opreator { get; set; }
public string value { get; set; }
}
public object[] conditions { get; set; }
public string name { get; set; }
}
But what I received the property conditions is just an object array. I can't access it's actual property, I even don't know it's actual type is(QueryVM.condition or array). I thinks the model binding even not set value of the properties. So this is a bad way.
I want know whether there is other way to do this?
UPDATE
The conditions property of QueryVM is an object array because it's contain object and array.
Conditions should be an array of type condition instead of simple object.
Try replacing
public object[] conditions { get; set; }
with
public condition[] conditions { get; set; }
actually you are sending list of type object because the type is not defined so you can do something like this
public List<object> conditions { get; set; }
this will get the list but your json should be like this
conditions:[{
"field": "",
"opreator": "",
"value": ""
},
{
"field": "",
"opreator": "",
"value": ""
}]
and your then your type will be
public List<condition> conditions { get; set; }

C# Deserialize list in JSON

Suppose I have JSON like this, how can I model my class for deserialization?
I have no problems to model class for standard attribute like "dummy" or normal arrays, but in this case, my "links" array is a list of items with different name ("addons", "conditions", "conversion", etc.).
"dummy": "1",
"links": {
"addons": {
"href": "/16071d9f-efec-4282-a42e-a495eea76ae0/offers/031C9E47-4802-4248-838E-778FB1D2CC05/addons",
"method": "GET"
},
"conditions": {
"href": "/16071d9f-efec-4282-a42e-a495eea76ae0/offers/031C9E47-4802-4248-838E-778FB1D2CC05/conditions",
"method": "GET"
},
"conversions": {
"href": "/16071d9f-efec-4282-a42e-a495eea76ae0/offers/031C9E47-4802-4248-838E-778FB1D2CC05/conversions",
"method": "GET"
},
"list_prices": {
"href": "/16071d9f-efec-4282-a42e-a495eea76ae0/offers/031C9E47-4802-4248-838E-778FB1D2CC05/list-prices",
"method": "GET"
},
"mutual_exclusion": {
"href": "/16071d9f-efec-4282-a42e-a495eea76ae0/offers/031C9E47-4802-4248-838E-778FB1D2CC05/mutually-exclusive-offers",
"method": "GET"
},
"prerequisites": {
"href": "/16071d9f-efec-4282-a42e-a495eea76ae0/offers/031C9E47-4802-4248-838E-778FB1D2CC05/prerequisites",
"method": "GET"
},
"product": {
"href": "/16071d9f-efec-4282-a42e-a495eea76ae0/products/f245ecc8-75af-4f8e-b61f-27d8114de5f3",
"method": "GET"
}
},
Assuming you are specifically looking for the set of LinkTypes if you will, in your JSON, could you use something like the following, and execute the Deserialize on the RootObject?
Working dotNet Fiddle: https://dotnetfiddle.net/ZWSlK4
Check out the output on the Console pane on the fiddle page.
public class Link
{
public string Href { get; set; }
public string Method { get; set; }
}
public class Links
{
[JsonProperty("addons")]
public Link Addons { get; set; }
[JsonProperty("conditions")]
public Link Conditions { get; set; }
[JsonProperty("conversions")]
public Link Conversions { get; set; }
[JsonProperty("list_prices")]
public Link ListPrices { get; set; }
[JsonProperty("mutual_exclusion")]
public Link MutualExclusion { get; set; }
[JsonProperty("prerequisites")]
public Link Prerequisites { get; set; }
[JsonProperty("product")]
public Link Product { get; set; }
}
public class RootObject
{
public string dummy { get; set; }
public Links links { get; set; }
}
and then execute the Deserializer like so.
var myDummyLinksList = JsonConvert.DeserializeObject<RootObject>(jsonText);
where jsonText contains the json string you have listed in your example:
However, if you List of links objects is dynamic and the number of objects inside varies and you need to capture all of them, then you might have to write a custom Converter that inherits from the JsonConverter object. then use the answer that #mfarouk has posted.
I forked my dotNet Fiddle and implemented his solution and it works like a boss for the dynamic case!
Working dotNet Fiddle (dynamic case): https://dotnetfiddle.net/7bFcNM
Hope this helps!
the links attribute could be parsed as key, value dictionary , the class can be like
public class JSONClass
{
public string dummy { get; set; }
public Dictionary<string, Link> links;
public class Link
{
public string Href { get; set; }
public string Method { get; set; }
}
}
then de-serialized as
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<JSONClass>(JSON);

Parse Json Array with different of keyvalue

In one of my project i want to parse a JSON array with different key name. For Example
{ "details": [
{ "state": "myState1",
"place": [
{ "name": "placeName" } ] },
{ "state": "myState2",
"place": [
{ "name1": "placeName" } ] },
{ "state": "myState3",
"place": [
{ "name2": "placeName" } ] } }
So in this JSON please look at the place array. each time key like name1,name2,name3...,
.And also it is not necessary to get the same JSON at all the time. In some time only state1 or state1 and state3 and in some time state1 to state 50.
So how can i identify and parse exact data from this array
First of all your JSON is not well-formatted. You miss a closing square bracket ] before the last closing curly bracket }.
Then, you can't parse variable-name properties to a static class, but you can turn them into a dictionary. Here's an example of mapping classes that work with variable places:
public class Details
{
public string state { get; set; }
public List<Dictionary<string, string>> place { get; set; }
}
public class Wrap
{
public Details[] details { get; set; }
}
static void Main(string[] args)
{
string txt = File.ReadAllText("MyJSONFile.txt");
JavaScriptSerializer ser = new JavaScriptSerializer();
var data = ser.Deserialize<Wrap>(txt);
}
If also the place property will change name, I think the simplest way to parse it is to use the following, very loosely typed, class:
public class Wrap
{
public List<Dictionary<string,object>> details { get; set; }
}
where the object in the dictionary will be a string or a dictionary of properties according to the values in the JSON.

Categories

Resources