I need to parse the following Json
{
"type": "send",
"data": "{"window":"true", "shell":"true", "wait":"false"}",
"tag": ""
}
I want data to be interpreted as a simple string:
"{"window":"true", "shell":"true", "wait":"false"}"
not as a json inside a json. How sholud I escape it?
{
"type": "send",
"data": '{"window":"true", "shell":"true", "wait":"false"}',
"tag": ""
}
The corresponding class generated by json2csharp
public class RootObject
{
public string type { get; set; }
public string data { get; set; }
public string tag { get; set; }
}
Solved it. The easiest thing to do is generate the json with simple json instead of doing it by hand.
Related
I am attempt to use an API that use the follow example structure for their returned json:
[{
"name":"Firs",
"id":"0",
"data": {"scale":"1","size":"500"}
},
{
"name":"Second",
"id":"1",
"data":"222"
}]
Upade "[ ]"
But I can not figure out how to get it to be happy with the provided structure.
Using Newtonsoft I am able to Serialize and Deserialize a model shown below:
List<RequestJson> requestJson = JsonConvert.DeserializeObject<List<RequestJson>>(json);
public class GetData
{
public int Scale { get; set; }
public int Size { get; set; }
}
public class RequestJson
{
public string Name { get; set; }
//Problem is here
public GetData Data { get; set; }
}
Your JSON is not valid. The Data property does not match the object type.
Correct JSON:
[{
"name":"Firs",
"id":"0",
"data": {"scale":"1","size":"500"}
},
{
"name":"Second",
"id":"1",
"data": {"scale":"2","size":"600"}
}]
The API I am working on requires a very complicated JSON object be passed in as a string, along with other values. So I created a class like this:
public class BURequest
{
public Guid ID { get; set; }
public string JSONStr { get; set; } --->JSON passed in as string
public string VersionName { get; set; }
}
The API controller has the following method:
public async Task<IActionResult> Check ([FromBody] BURequest testRequest)
However I kept getting "After parsing a value an unexpected character was encountered: c. Path 'BURequest', line 4, position 3."
Here is the JSON string:
{
"content_version": "1",
"date_created": "2020-10-06T13:52:15.288Z",
"date_updated": "2020-10-06T13:54:24.325Z",
"tools": {
"car": true,
"truck": true
}
}
Is there any way to get around this problem without having to create a class for the JSON object itself? It's a complicated object and has a huge number of properties. Thanks!
p.s.I've verified that the JSON string is valid using JSONLint as suggested below.
I would use JsonElement for this:
public class BURequest
{
public Guid ID { get; set; }
public JsonElement JSONStr { get; set; } --->JSON passed in as string
public string VersionName { get; set; }
}
And then just get the value:
testRequest.JSONStr.ToString()
The Json needs to be:
{
"JSONStr" : {
"content_version": "1",
"date_created": "2020-10-06T13:52:15.288Z",
"date_updated": "2020-10-06T13:54:24.325Z",
"tools": {
"car": true,
"truck": true
}
}
}
Just adding an answer to go with the comment on the question. Changing the type of the JSONStr property from string to JObject solves the problem.
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.
I have a JSON list of players for a game. I need the program to be able to read the JSON file and give me the list of players. Then I can use this list of players to get each player's name and who they are following.
{
"Version": "1",
"Users": [
{
"UserName": "CoolDude",
"Following": [ "SniperElitez", "IamAwesome" ]
},
{
"UserName": "GamerChick",
"Following": [ "IamAwesome", "NoWayBro", "WowWhoMe", "SniperElitez", "SurfingIsFun", "NowUTry" ]
},
{
"UserName": "SurfingIsFun",
"Following": [ "WowWhoMe" ]
},
{
"UserName": "IamAwesome",
"Following": [ "GamerChick", "NoWayBro" ]
},
{
"UserName": "NowUTry",
"Following": [ "GamerChick", "SniperElitez" ]
},
{
"UserName": "SniperElitez",
"Following": [ "SurfingIsFun", "IamAwesome" ]
},
{
"UserName": "WowWhoMe",
"Following": [ "NoWayBro", "GamerChick", "SniperElitez" ]
},
{
"UserName": "NoWayBro",
"Following": [ "GamerChick", "IamAwesome", "SniperElitez" ]
}
]
}
Here is the code I'm trying to use currently
Player Class
class Player
{
public string UserName { get; set;}
public List<string> Following { get; set;}
}
PlayerList Class
class PlayerList
{
public List<Player> pList { get; set; }
}
Main
{
string json = File.ReadAllText("friends.json");
// this gives me a playerList object
PlayerList playerList = JsonConvert.DeserializeObject<PlayerList>(json);
}
Supposedly the PlayerList object is not null but the List is empty. If anyone can tell me how to turn the JSON into the PlayerList object and then from there, get player's variables like UserName, I would greatly appreciate it!
Visual Studio has a nice feature for parsing XML / JSON... namely, if you copy an XML or a JSON to your clipboard then you can use Edit -> Paste Special -> Paste JSON As Classes command and have VS automatically generate valid model classes.
In case of your JSON this is the output my VS generated:
public class Rootobject
{
public string Version { get; set; }
public User[] Users { get; set; }
}
public class User
{
public string UserName { get; set; }
public string[] Following { get; set; }
}
Try that.
Also, you're using JsonConvert, which appears to be something by Newtonsoft. I have no idea if it's a good library or not, but there ARE .NET classes which are capable of deserializing JSON. The linked question offers one method. Another is to use a DataContractJsonSerializer, albeit I think the model classes would need to have the [DataContract] and [DataMember] attributes added to them to work with that.
The reason is that in the json doc the attribute is called "Users" and in your code you have called it "pList".
There are two solutions to this:
Rename PlayerList.pList to PlayerList.Users
Add a JsonProperty attribute on the property to set its name like this:
class PlayerList
{
[JsonProperty(PropertyName = "Users")]
public List pList { get; set; }
}
I was able to get this working by following what was stated in the question at the following link:
How to deserialize an JObject to .NET object
Here is my code:
var playerList = JsonConvert.DeserializeObject(json);
JObject jObject = ((JObject)playerList);
PlayerList users = jObject.ToObject<PlayerList>();
I also renamed the pList to Users on the PlayerList Class.
I've been trying to figure out why some of my tests haven't been working (TDD) and managed to track it down to serialization of a class, but I'm not sure why it's not working. There are two flavours, a simple version and a more complex version, the slightly more complicated one involves having an array of values within the Parameter.Value.
The simple version, I've got a class that can be serailzied using the JavaScriptSerializer (I'm assuming this is how MVC works when it generates JSON). The structure it produces looks like this:
{
"Name": "TestQuery",
"QueryId": 1,
"Parameters": [
{
"Name": "MyString",
"DataType": 0,
"Value": "A String",
"IsArray": false
}],
"Sql": "SELECT * FROM Queries"
}
There are 3 C# classes Query, ParameterCollection (which is a KeyedCollection<String, Parameter>) and a Parameter. All of these are marked up with DataContract/DataMember attributes and serialize via the DataContractSerializer without any problem.
The JavaScriptSerializer however, serializes the object correctly to the JSON above, but upon deserialization I have no Parameters, they just seem to get missed off.
Does anyone have any idea why these fails, and what I might be able to do to fix it?
Why KeyedCollection<String, Parameter>? You have an array, not dictionary, so your JSON should match the following structure:
public class Query
{
public int QueryId { get; set; }
public string Name { get; set; }
public string Sql { get; set; }
public Parameter[] Parameters { get; set; }
}
public class Parameter
{
public string Name { get; set; }
public int DataType { get; set; }
public string Value { get; set; }
public bool IsArray { get; set; }
}
and then you will be able to deserialize it without any problems:
var serializer = new JavaScriptSerializer();
var json = #"
{
""Name"": ""TestQuery"",
""QueryId"": 1,
""Parameters"": [
{
""Name"": ""MyString"",
""DataType"": 0,
""Value"": ""A String"",
""IsArray"": false
}],
""Sql"": ""SELECT * FROM Queries""
}";
var query = serializer.Deserialize<Query>(json);
Also you can get rid of [Data*] attributes from your view models, they are not used by the JavaScriptSerializer class.