Deserializing JSON with 'space' separated property names - c#

I need to deserialize a json which has got property names with a 'space' in between them ('Associated Team' and 'Point of Contact'). I have tried deserializing the json string by creating a strongly typed object but it is unable to map these 2 properties.
JSON string: (jsonString)
{
"id": "/subscriptions/911yyy-1234-4695-a90f-943xxxxxxx/resourceGroups/sample",
"name": "sample",
"type": null,
"properties": {
"provisioningState": "Succeeded"
},
"location": "westus",
"tags": {
"Associated Team": "Sample Team",
"Description": "Resource Group for Azure",
"Point of Contact": "abc#xyz.com"
}
}
.Net code snippet:
var deserializedResourceGroupDetails = JsonConvert.DeserializeObject<AzureResourceData>(jsonString);
AzurResourceData.cs class:
public class Tags
{
[JsonProperty("associatedTeam")]
public string associatedTeam { get; set; }
public string description { get; set; }
[JsonProperty("pointOfContact")]
public string pointOfContact { get; set; }
}
public class Properties
{
public string provisioningState { get; set; }
}
public class AzureResourceData
{
public string id { get; set; }
public string name { get; set; }
public string location { get; set; }
public Tags tags { get; set; }
public Properties properties { get; set; }
}
I have also tried deserializing the json dynamically(below) but then again I am unable to get the values of the two properties because they have got space in between their names.
dynamic deserializedResourceGroupDetails = JsonConvert.DeserializeObject(jsonString)));

Your [JsonProperty] should exactly match the key of your JSON object. So your Tags class should look like this:
public class Tags
{
[JsonProperty("Associated Team")] //this one changed
public string associatedTeam { get; set; }
public string description { get; set; }
[JsonProperty("Point of Contact")] //this one too
public string pointOfContact { get; set; }
}
This way, JSON knows where to map those keys in your file that aren't literally in your code.

Related

Deserialize json to List<object> in C#

I have the following JSON string
{
"data": [
{
"symbol": "1COV.GE",
"exposure": "0",
"makerExposure": "-2028",
"takerExposure": "2028",
"makerPnl": "447.6688",
"takerPnl": "-447.6688",
"makerPositions": [
{
"name": "IB_001",
"position": "-2028",
"vwap": "47.41",
"pnl": "447.6688"
}
],
"takerPositions": [
{
"name": "MT5_1",
"position": "2028",
"vwap": "47.41",
"pnl": "-447.6688"
}
]
},
{
"symbol": "A",
"exposure": "0",
"makerExposure": "-10",
"takerExposure": "10",
"makerPnl": "-4.6",
"takerPnl": "4.6",
"makerPositions": [
{
"name": "IB_002",
"position": "-10",
"vwap": "136.78",
"pnl": "-4.6"
}
],
"takerPositions": [
{
"name": "MT5_1",
"position": "10",
"vwap": "136.78",
"pnl": "4.6"
}
],
"total": 2
}
}
And my goal is to serialize it into a List of object from the NODE "Data":
I have the classes that map the data node fields:
public class Positions
{
public string name { get; set; }
public string position { get; set; }
public string vwap { get; set; }
public string pnl { get; set; }
}
public class ExPositions
{
public string symbol { get; set; }
public string exposure { get; set; }
public string makerExposure { get; set; }
public string takerExposure { get; set; }
public string makerPnl { get; set; }
public string takerPnl { get; set; }
public OZPositions makerPositions { get; set; }
public OZPositions takerPositions { get; set; }
}
Do you have any ideas how I can convert the node "data" to list of "ExPositions" objects, eg. List
I've did this but so far it throws an error
var positions = JsonSerializer.Deserialize<ExPositions>(json_string);
There is an error in your json - it's missing a closing ] for the array (I'll assume it's a typo).
The real problem is that you need a wrapper class to represent the data node of the json which should contain a list (or array) of ExPositions. The makerPositions and takerPositions should also become lists (or arrays) too. Add the following class and update the position properties of ExPositions:
public class Data
{
public List<ExPositions> data { get; set; }
}
// change positions to use a List too
public class ExPositions
{
...
public List<Positions> makerPositions { get; set; }
public List<Positions> takerPositions { get; set; }
}
Then you can deserialize using:
var result = JsonSerializer.Deserialize<Data>(json);
It's not clear where the ""total"": 2 property should be in your models (it's not clear in the json because of the issue I mentioned), you could add it to the Data class above (if it belongs there).
Online demo
Try with:
public class Positions
{
public string name { get; set; }
public string position { get; set; }
public string vwap { get; set; }
public string pnl { get; set; }
}
public class ExPositions
{
public string symbol { get; set; }
public string exposure { get; set; }
public string makerExposure { get; set; }
public string takerExposure { get; set; }
public string makerPnl { get; set; }
public string takerPnl { get; set; }
public Positions makerPositions { get; set; }
public Positions takerPositions { get; set; }
}
public class YourResult{
public ExPositions data { get; set; }
public int total { get; set; }
}
And then call:
var positions = JsonSerializer.Deserialize<YourResult>(json_string);
As haldo mentioned, there is a typo in your JSON. To quickly parse and validate your JSON data, you can use any online JSON parsers to validate your JSON data. I usually use the chrome extension JSON Viewer Pro.
Also, in the link that haldo provided to the .NET Fiddle for the demo, there is a trailing comma in JSON data which JSON deserializers might not ignore.
Here is the link to the edited demo that haldo provided.
Edited Demo

Deserialize JSON using specific properties

I'm trying to deserialize JSON without declaring every property in C#. Here is a cut-down extract of the JSON:
{
"resourceType": "export",
"type": "search",
"total": 50,
"timestamp": "2020-08-02T18:26:06.747+00:00",
"entry": [
{
"url": "test.com/123",
"resource": {
"resourceType": "Slot",
"id": [
"123"
],
"schedule": {
"reference": {
"value": "testvalue"
}
},
"status": "free",
"start": "2020-08-03T08:30+01:00",
"end": "2020-08-03T09:00+01:00"
}
}
]
}
I want to get the values out of entry → resource, id and start.
Any suggestions on the best way to do this?
I've made very good experiences with json2sharp. You can enter your JSON data there and it will generate the classes you need to deserialize the JSON data for you.
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
public class Root
{
public string resourceType { get; set; }
public string type { get; set; }
public int total { get; set; }
public DateTime timestamp { get; set; }
public List<Entry> entry { get; set; }
}
The next step is to choose a framework which will help you to deserialize. Something like Newtonsoft JSON.
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
If you want to get the data without declaring classes, you can use Json.Net's LINQ-to-JSON API (JToken, JObject, etc.). You can use the SelectToken method with a JsonPath expression to get what you are looking for in a couple of lines. Note that .. is the recursive descent operator.
JObject obj = JObject.Parse(json);
List<string> ids = obj.SelectToken("..resource.id").ToObject<List<string>>();
DateTimeOffset start = obj.SelectToken("..resource.start").ToObject<DateTimeOffset>();
Working demo here: https://dotnetfiddle.net/jhBzl4
If it turns out there are actually multiple entries and you want to get the id and start values for all of them, you can use a query like this:
JObject obj = JObject.Parse(json);
var items = obj["entry"]
.Children<JObject>()
.Select(o => new
{
ids = o.SelectToken("resource.id").ToObject<List<string>>(),
start = o.SelectToken("resource.start").ToObject<DateTimeOffset>()
})
.ToList();
Demo: https://dotnetfiddle.net/Qe8NB7
I am not sure why you don't deserialize the lot (even if it's minimally populated) since you have to do the inner classes anyway.
Here is how you could bypass some of the classes (1) by digging into the JObjects
Given
public class Reference
{
public string value { get; set; }
}
public class Schedule
{
public Reference reference { get; set; }
}
public class Resource
{
public string resourceType { get; set; }
public List<string> id { get; set; }
public Schedule schedule { get; set; }
public string status { get; set; }
public string start { get; set; }
public string end { get; set; }
}
public class Entry
{
public string url { get; set; }
public Resource resource { get; set; }
}
You could call
var results = JObject.Parse(input)["entry"]
.Select(x => x.ToObject<Entry>());

How to convert list of raw data to list of Json?

I have the following classes :
public class Solution
{
public string Id { get; set; }
public string ProjectName { get; set; }
public string CodeName { get; set; }
public string Description { get; set; }
public string Author { get; set; }
public string Createdate { get; set; }
public string LastEditedBy { get; set; }
public string Status { get; set; }
public string GoLive { get; set; }
public virtual List<State> States { get; set; }
}
public class State
{
public Solution Solution { get; set; }
public string SolutionId { get; set; }
public string StateId { get; set; }
public string StateValue { get; set; }
}
Where StateValue is raw json string.
When I want to deserialise this I get a json string with \r\n .
Ho to tell the json serializer to not escape that string and treat it as json because it is already json.
I want an output like this :
[
{
"id": "43c7f6d5-61dc-4c1c-8c76-e13878b7483f",
"projectName": "Test Request 2",
"codeName": "",
"description": "",
"author": "",
"createdate": "02/13/2019",
"lastEditedBy": "",
"status": "Pending",
"goLive": "02/13/2019",
"states": [
{
"id": "cd7363f8-752b-4eb2-aaa2-ef94d7685153",
"label": "Empty State",
"layerone": [
{
"StorageCloudPhysical_Custom3": "cc1",
"StorageCloudPhysical_WorkSpace": "ws for asset 2"
},
{
"StorageCloudPhysical_Custom3": "cc3",
"StorageCloudPhysical_WorkSpace": "ws for asset 4"
}
}
]
}
]
States in the json schema is the value of the operation Solution.States.Select(s => s.StateValue), which is something like List.
How can I achieve this please and thanks in advance.
EDITED:
What is your project type? Is it C# MVC?
First of all, you need to install the NewtonSoft library using Nuget, then, instantiate it on your controller.
Newtonsoft
using Newtonsoft.Json;
Now, you just "convert" your list, to a JsonList using serialize to do that.
var list = JsonConvert.SerializeObject<List<string>>(YorRawList).ToList();

Classes to fit a JSON format — is this possible?

I've been trying create c# classes to map to a JSON format required by a service. But failing to find the right answer.
Here is the JSON:
{
"request": {
"path": "1",
"coverages": {
"path": "2",
"broadcastCoverage": {
"path": "3",
"name": "First Coverage",
"channel": "Channel 9",
"callSign": "DSOTM"
},
"internetCoverage": {
"path": "4",
"name": "Second Coverage",
"url": "www.stackoverflow.com"
},
"thirdCoverage": {
"path": "5",
"name": "Third Coverage",
"differentProperty": "Units"
}
}
}
}
If I put this into a JSON to C# converter I get the following:
public class BroadcastCoverage
{
public string path { get; set; }
public string name { get; set; }
public string channel { get; set; }
public string callSign { get; set; }
}
public class InternetCoverage
{
public string path { get; set; }
public string name { get; set; }
public string url { get; set; }
}
public class ThirdCoverage
{
public string path { get; set; }
public string name { get; set; }
public string differentProperty { get; set; }
}
public class Coverages
{
public string path { get; set; }
public BroadcastCoverage broadcastCoverage { get; set; }
public InternetCoverage internetCoverage { get; set; }
public ThirdCoverage thirdCoverage { get; set; }
}
public class Request
{
public string path { get; set; }
public Coverages coverages { get; set; }
}
public class RootObject
{
public Request request { get; set; }
}
But I need different types of Coverages (Broadcast, Internet, others) to be variable so I tried taking those out of the Coverages class and added a property:
public Dictionary<string, CoverageBase> CoverageList { get; set; }
Which will allow me to choose which coverages to include, the problem then becomes the CoverageList property name is in the JSON when it is serialized. I essentially would like a key/value (string, CoverageBase) without the property name.
Is there a way to add key value pairs without having the property name in the JSON? I've seen examples where this is done at the root object level but I haven't been able to find any example where it nested within the JSON.
If this can't be done with a simple object model what would be a recommended method to get the JSON built?
UPDATE: I like the answer that utilizes JsonSubTypes as it doesn't require much code, however I can't use a 3rd party library outside of json.net. Is there a way to accomplish this using a JsonConverter?
I think its possible as checked here, however it seems your app needs to reconstruct the json in a format where it includes the C# typings. More documentation here.
EDIT:
Thanks to dbc's reference I was able to dive in to the JsonSubtypes and its pretty easy to implement.
Here's my code base structure.
[JsonConverter(typeof(JsonSubtypes))]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(BroadcastCoverage), "channel")]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(InternetCoverage), "url")]
[JsonSubtypes.KnownSubTypeWithProperty(typeof(ThirdCoverage), "differentProperty")]
public class CoverageBase
{
public string path { get; set; }
public string name { get; set; }
}
public class BroadcastCoverage : CoverageBase
{
public string channel { get; set; }
public string callSign { get; set; }
}
public class InternetCoverage : CoverageBase
{
public string url { get; set; }
}
public class ThirdCoverage : CoverageBase
{
public string differentProperty { get; set; }
}
public class Request
{
public string path { get; set; }
public List<CoverageBase> coverages { get; set; }
}
However the Json you're receiving was not quite ideally structured, so I did some reformatting just to let it to be properly parsed.
string json = "{\"request\":{\"path\":\"1\",\"coverages\":{\"path\":\"2\",\"broadcastCoverage\":{\"path\":\"3\",\"name\":\"First Coverage\",\"channel\":\"Channel 9\",\"callSign\":\"DSOTM\"},\"internetCoverage\":{\"path\":\"4\",\"name\":\"Second Coverage\",\"url\":\"www.stackoverflow.com\"},\"thirdCoverage\":{\"path\":\"5\",\"name\":\"Third Coverage\",\"differentProperty\":\"Units\"}}}}";
var jsonReq = JObject.Parse(json);
var pathVal = jsonReq["request"]["path"].Value<string>();
var coverageObjects = jsonReq["request"]["coverages"].Value<JObject>();
var filteredObjects = coverageObjects.Children().Where(x => x.Value<JProperty>().Name.EndsWith("Coverage"));
var dictionary = filteredObjects.Select(x => new KeyValuePair<string, string>(x.Value<JProperty>().Name, x.Value<JProperty>().Value.ToString()));
// reformatted Json
var newJson = "{ \"path\":\"" + pathVal + "\", \"coverages\" : [" + String.Join(",", dictionary.Select(x => x.Value).ToList()) + "]}";
Request reqC = JsonConvert.DeserializeObject<Request>(newJson);

Cannot deserialize the JSON array (e.g. [1,2,3]) into type ' ' because type requires JSON object (e.g. {“name”:“value”})

I have JSON returning in the following format:
{
"Items": [
{
"unique_id": "11111111111",
"rages": {
"rage_content": "Hello rage 2",
"date_stamp": "21/07/2017",
"id": 2
}
},
{
"unique_id": "2222222222",
"rages": {
"rage_content": "Hello rage 1",
"date_stamp": "21/07/2017",
"id": 1
}
}
],
"Count": 2,
"ScannedCount": 2
}
And I have the following 2 classes defined:
Items.cs:
namespace ragevent_A0._0._1
{
class Items
{
public String rage_id { get; set; }
public rage rage { get; set; }
}
}
rage.cs:
class rage
{
public String rage_content { get; set; }
public String date_stamp { get; set; }
public int id { get; set; }
}
I am using the following code in order to attempt to deseralize the JSON returned above:
List<Items> data = JsonConvert.DeserializeObject<List<Items>>(json);
However, I am not able to successfully deserialize the data due to the above error. I have tried a few solutions online, however I have not managed to find a solution which works with the format of my returned JSON. I have used a JSON formatter and it is formatted correctly, so that shouldn't be the issue.
Any help would be much appreciated!
For the posted JSON data below should be the model you need (credit: http://json2csharp.com/). There is mismatch between the property name rage_id. You can use JsonProperty attribute
public class Rages
{
public string rage_content { get; set; }
public string date_stamp { get; set; }
public int id { get; set; }
}
public class Item
{
[JsonProperty(Name="rage_id")]
public string unique_id { get; set; }
public Rages rages { get; set; }
}
public class RootObject
{
public List<Item> Items { get; set; }
public int Count { get; set; }
public int ScannedCount { get; set; }
}
Your deserialization should be
var data = JsonConvert.DeserializeObject<RootObject>(json);

Categories

Resources