Can't seem to get this working. I have this json string and I want to convert it to a C# object:
{"name":"mousePos","args":[{"mouseDet":{"rid":"1","posx":1277,"posy":275}}]}
I've been trying JavaScriptSerializer but I'm having no luck. I'm unsure how to get the values of posx and posy. Can anyone suggest how I would do this? Thanks for the help.
EDIT:
public class JsonData
{
public string name { get; set; }
}
public Form1()
{
// ---- Other stuff here ----
string json = data.MessageText; // The json string.
JavaScriptSerializer ser = new JavaScriptSerializer();
JsonData foo = ser.Deserialize<JsonData>(json);
MessageBox.Show(foo.name); // Shows 'mousePos'
}
I dropped that into JsonLint and got an error. Its invalid JSON
{
"name": "mousePos",
"args": [
"mouseDet": {
"rid": "1",
"posx": 1277,
"posy": 275
}
} //-- THIS should not be here.
]
}
You just need to extend out your object model a little bit to cover it. Based on what you've got in your example, it would be something like:
public class JsonData
{
public string name { get; set; }
public Arguments[] args { get; set; }
}
public class Arguments
{
public MouseDet mouseDet { get; set; }
}
public class MouseDet
{
public int rid { get; set; }
public int posx { get; set; }
public int posy { get; set; }
}
...
var posx = foo.args[0].mouseDet.posx;
The reason the JSON is not valid is because your "args" property contains a key/value pair inside of square brackets, which is not a valid array. I'm guessing it should be something like:
{
"name":"mousePos",
"args":[{"mouseDet":{"rid":"1","posx":1277,"posy":275}}]
}
Related
I've got the following json document:
{
"name": "bert",
"Bikes": {
"Bike1": {
"value": 1000,
"type": "Trek"
},
"Bike2": {
"value": 2000,
"type": "Canyon"
}
}
}
With potentially other bikes like Bike3...BikeN. I want to deserialize to C# objects. Problem is that in the deserialization step the bikes data is completely lost, resulting in a null Bikes collection.
Code to reproduce:
[Test]
public void FirstCityJsonParsingTest()
{
var file = #"./testdata/test.json";
var json = File.ReadAllText(file);
var res = JsonConvert.DeserializeObject<Person>(json);
Assert.IsTrue(res.Name == "bert");
// next line is failing, because res.Bikes is null...
Assert.IsTrue(res.Bikes.Count == 2);
}
public class Bike
{
public string Id { get; set; }
public int Value { get; set; }
public string Type { get; set; }
}
public class Person
{
public string Name { get; set; }
public List<Bike> Bikes { get; set; }
}
To fix this problem a change in the used model is necessary. But what change is needed here to fill the bikes data correctly?
Note: Changing the input document is not an option (as it's a spec)
Your code structure is not reflecting your json. Common approach to deserializing json with dynamic property names is to use Dictionary<string, ...> (supported both by Json.NET and System.Text.Json). Try the following:
public class Bike
{
public int Value { get; set; }
public string Type { get; set; }
}
public class Person
{
public string Id { get; set; }
public string Name { get; set; }
public Dictionary<string, Bike> Bikes { get; set; }
}
Person.Bikes should be changed to Dictionary<string, Bike> (also Bike.Id property is not needed) cause Bikes json element is not an array but object.
I am using this code to read a json file firstSession.json and display it on a label.
var assembly = typeof(ScenarioPage).GetTypeInfo().Assembly;
string jsonFileName = "firstSession.json";
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new StreamReader(stream))
{
var json = reader.ReadToEnd(); //json string
var data = JsonConvert.DeserializeObject<SessionModel>(json);
foreach (SessionModel scenario in data)
{
scenarioName.Text = scenario.title;
break;
}
scenarioName.Text = data.title; // scenarioName is the name of the label
}
SessionModel.cs looks like:
public class SessionModel : IEnumerable
{
public int block { get; set; }
public string name { get; set; }
public string title { get; set; }
public int numberMissing { get; set; }
public string word1 { get; set; }
public string word2 { get; set; }
public string statement1 { get; set; }
public string statement2 { get; set; }
public string question { get; set; }
public string positive { get; set; } // positive answer (yes or no)
public string negative { get; set; } // negative answer (yes or no)
public string answer { get; set; } // positive or negative
public string type { get; set; }
public string format { get; set; }
public string immersion { get; set; }
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}
The beginning of my json is:
{
"firstSession": [
{
"block": 1,
"name": "mark",
"title": "mark's house",
"numberMissing": 1,
"word1": "distracted",
"word2": "None",
"statement1": "string 1",
"statement2": "None",
"question": "question",
"positive": "No",
"negative": "Yes",
"answer": "Positive",
"type": "Social",
"format": "Visual",
"immersion": "picture"
},
I am getting a Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object into type "MyProject.SessionModel" because the type requires a JSON array to deserialize correctly. To fix this error either change the JSON to a JSON array or change the deserialized type so that it is a normal .NET type that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'firstSession', line 2, position 17.
How can I convert the json string to a json array? Or make one of the other modifications the debugger suggests?
you need to create a wrapper class (json2csharp.com will help you do this)
public class Root {
public List<SessionModel> firstSession { get; set; }
}
then
var data = JsonConvert.DeserializeObject<Root>(json);
data.firstSession will be a List<SessionModel>
Create a new Class and have firstSession as List of SessionModel.
public class Sessions
{
public List<SessionModel> firstSession { get; set; }
}
Remove IEnumerable from the SessionModel
public class SessionModel
{
public int block { get; set; }
public string name { get; set; }
public string title { get; set; }
}
Change thedeserialization part as follows
var data = JsonConvert.DeserializeObject(line);
foreach (SessionModel scenario in data.firstSession)
{
//Here you can get each sessionModel object
Console.WriteLine(scenario.answer);
}
Im having trouble in parsin JSON in C#. I want to parse this Json Format.
{
"data":
[
{
"id": 3,
"code": "0000004",
}
]
}
Here is my code in C#.
public Data data { get; set; }
public class Data
{
public string id { get; set; }
public string code { get; set; }
}
The JSON shown is an object that has (as data) an array of elements that have an id and code, so:
public class SomeRoot {
public List<Data> data {get;} = new List<Data>();
}
and deserialize a SomeRoot and you should be fine:
var root = JsonConvert.DeserializeObject<SomeRoot>(json);
var obj = root.data[0];
Console.WriteLine(obj.id);
Console.WriteLine(obj.code);
You are missing an essential part, the outer object. Also, the data is an array:
public class RootObject
{
public Data[] data { get; set; }
}
RootObject r = JsonConvert.DeserializeObject<RootObject>(json);
Next time, follow the steps as outlined in Easiest way to parse JSON response. It will help you generate the correct class.
It should be :
public class Data
{
public int id { get; set; }
public string code { get; set; }
}
public class RootObject
{
public List<Data> data { get; set; }
}
I am trying to deserialise some JSON that I get back from an API so that I can loop through an array of county names and add the information to a datatable in C#. However I am receiving following error at the first hurdle when I try and deserialise it:
error: System.MissingMethodException: No parameterless constructor defined for type of 'DPDJSONLibrary.DPD_JSON+LOCR_Data[]'.
The provider of the API provides an example of the JSON response as follows:
{
"error": null,
"data":[{
"country": [{
"countryCode":"GB",
"countryName":"United Kingdom",
"internalCode":"UK",
"isEUCountry":false,
"isLiabilityAllowed":false,
"isoCode":"826",
"isPostcodeRequired":false,
"liabilityMax":15000
}]
}]
}
A sample of the JSON data I am getting back from the API is:
{
"data": {
"country":[
{
"countryCode":"PM",
"countryName":"St Pierre & Miquilon",
"isoCode":"666",
"isEUCountry":false,
"isLiabilityAllowed":true,
"liabilityMax":15000,
"isPostcodeRequired":true
},
{
"countryCode":"SR",
"countryName":"Suriname",
"isoCode":"740",
"isEUCountry":false,
"isLiabilityAllowed":true,
"liabilityMax":15000,
"isPostcodeRequired":true
},
{
"countryCode":"SZ",
"countryName":"Swaziland",
"isoCode":"748",
"isEUCountry":false,
"isLiabilityAllowed":true,
"liabilityMax":15000,
"isPostcodeRequired":true
}
]
}
}
I have tried to make some classes to put the JSON in as follows:
/// <summary>
/// List Of Countries Response object.
/// </summary>
public class LOCR
{
public LOCR_Error error { get; set; }
public LOCR_Data[] data { get; set; }
}
public class LOCR_Error
{
public string errorAction { get; set; }
public string errorCode { get; set; }
public string errorMessage { get; set; }
public string errorObj { get; set; }
public string errorType { get; set; }
}
public class LOCR_Data
{
public LOCR_Data_Country[] country { get; set; }
}
public class LOCR_Data_Country
{
public string countryCode { get; set; }
public string countryName { get; set; }
public string internalCode { get; set; }
public bool isEUCountry { get; set; }
public bool isLiabilityAllowed { get; set; }
public string isoCode { get; set; }
public bool isPostcodeRequired { get; set; }
public int liabilityMax { get; set; }
}
When I get the JSON back as a string, I am trying to use the Newtonsoft (plugin?) to put it into my classes using:
JavaScriptSerializer ser = new JavaScriptSerializer();
DPD_JSON.LOCR DPDCountries = new DPD_JSON.LOCR();
DPDCountries = ser.Deserialize<DPD_JSON.LOCR>(data);
It is the last line above that is generating the error. I suspect I've written my classes wrong that I am trying to deserialise the JSON in to - can anyone see where I've gone wrong?
Deserialize will return a list and not an array, So your LOCR_Data_Country should be of type List and not array:
public class LOCR_Data
{
public List<LOCR_Data_Country> country { get; set; }
}
There's a HUGE difference between the two example JSON strings you've shown. Mainly the first one is an array : "data":[ ... ] and the second one is an object "data:{ ... }. These two are not interchangeable so you have to stick to either one of those. If the thing you're getting back from the API is an object instead you should rewrite your model to be :
public class LOCR
{
public LOCR_Error error { get; set; }
// object here since "data": { ... }
public LOCR_Data data { get; set; }
}
And as you move further with the JSON you can see that LOCR_Data.country is in fact an array in both cases "country": [ ... ] so you can stick with the current implementation of LOCR_Data class.
Try Using :
YourResultClass object = JsonConvert.DeserializeObject<YourResultClass>(Jsonstring);
See the answer of this Using JsonConvert.DeserializeObject to deserialize Json
OR
dynamic data = Json.Decode(json);
You can refer this Deserialize JSON into C# dynamic object? for further assistance
using Telerik.Newtonsoft.Json;
MVC Controller:
public ActionResult Index()
{
string responseStr = GetJSON();
var jObject = JsonConvert.DeserializeObject<TheViewModel>(responseStr);
if (jObject == null)
{
return Content("");
}
return View("Default", jObject);
}
Temporary hard coded JSON method:
public string GetJSON() //to be replaced after testing
{
string json = #"{
'name': 'Trial 11.7',
'id': 2599,
'version': '11.7',
'product_id': '1040',
'time_of_execution': '2017-08-07T22:15:38.000Z',
'site_url': 'http://something.com/',
'mc_gem': '11.7',
'suite_gem': '11.7',
'passing_percentage': 95.65,
'failing_percentage': 4.35
}";
return json;
}
The model:
public class TheViewModel
{
public class RootObject
{
public string name { get; set; }
public int id { get; set; }
public string version { get; set; }
public string product_id { get; set; }
public string time_of_execution { get; set; }
public string site_url { get; set; }
public string mc_gem { get; set; }
public string suite_gem { get; set; }
}
}
The problem is that I get the following as the value when I step through the code:
jObject {Master.Project.Mvc.Models.TheViewModel} Master.Project.Mvc.Models.TheViewModel
For some reason I am not getting the JSON deserialized into the object. It is probably something simple, but I am not seeing it.
I receive no error message to help determine the issue inside the controller.
Any help would be appreciated.
You're trying to convert the JSON to an object of type TheViewModel when it's looking for a type of RootObject
You can fix this by either moving all of the fields in RootObject out and into TheViewModel or by calling ...DeserializeObject<TheViewMode.RootObject>(responseStr);
Refactor your code, extract the 'RootObject' class to its own file (or move it so that it is not defined under a class.) will solve the problem.