I am learning how to work with json data using Newtonsoft.Json.
I stored my valid json file in a folder in my console application and calling
a method that will process the json file.
static void Main(string[] args)
{
IEnumerable<IEnumerable<string>> result;
string pathToFile = #"C:\DevelopmentJson\ConsoleApp1\File\my_test.json";
MyReader objReader = new MyReader();
result = objReader.Export(pathToFile).ToList();
Console.WriteLine("Hello");
}
Here is the method within my class that is been called.
public IEnumerable<IEnumerable<string>> Export(string json)
{
var document = JToken.Parse(json);
var data = new List<List<string>>();
.....
return data;
}
I am beginning to feel I cannot use a pathToFile as a path to my json file.
I started to get the error message below on this line [var document = JToken.Parse(json);]
Newtonsoft.Json.JsonReaderException:
'Unexpected character encountered while parsing value: C. Path '', line 0, position 0.'
How do I resolve this error message?
The Newtonsoft Json.NET documentation has two examples showing how to deserialize JSON from a file. Below are both examples with minor modifications to help integrate with your code.
Option 1. Reading JSON data via JsonConvert
var pathToFile = #"C:\DevelopmentJson\ConsoleApp1\File\my_test.json";
// read file into a string and deserialize JSON to a type
var dataFromJsonConvert = JsonConvert.DeserializeObject<MyData>(File.ReadAllText(pathToFile));
// dataFromJsonConvert now holds your JSON data from file
Option 2. Reading JSON data via JsonSerializer
var pathToFile = #"C:\DevelopmentJson\ConsoleApp1\File\my_test.json";
// deserialize JSON directly from a file
using (StreamReader file = File.OpenText(pathToFile))
{
var serializer = new JsonSerializer();
var dataFromJsonSerializer = (IEnumerable<IEnumerable<string>>)serializer.Deserialize(file, typeof(MyData));
// dataFromJsonSerializer now holds your JSON data from file
}
Example demonstrating how to utilize answer
static void Main(string[] args)
{
var pathToFile = "C:\DevelopmentJson\ConsoleApp1\File\my_test.json";
var fileJsonRaw = File.ReadAllText(pathToFile))
var objReader = new MyReader();
var fileJsonParsed = objReader.Export(fileJsonRaw).ToList();
Console.WriteLine("Hello");
}
public MyData Export(string json)
{
return JsonConvert.DeserializeObject<MyData>(json);
}
Classes generated from your JSON data
The classes below were generated from your sample JSON. These classes are used within answer to demonstrate a complete solution.
public partial class MyData
{
[JsonProperty("UpdatedDay")]
public string UpdatedDay { get; set; }
[JsonProperty("UpdatedUser")]
public string UpdatedUser { get; set; }
[JsonProperty("solution")]
public Solution[] Solution { get; set; }
}
public partial class Solution
{
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("fields")]
public Field[] Fields { get; set; }
}
public partial class Field
{
[JsonProperty("firstname")]
public string Firstname { get; set; }
[JsonProperty("lastiname", NullValueHandling = NullValueHandling.Ignore)]
public string Lastiname { get; set; }
[JsonProperty("required")]
public bool FieldRequired { get; set; }
[JsonProperty("lastname", NullValueHandling = NullValueHandling.Ignore)]
public string Lastname { get; set; }
}
Note: The following using statements are necessary.
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
JToken.Parse doesn't take a path, it takes the actual json string.
You can get the contents of the file with File.ReadAllText.
Something like this (checks etc omitted):
public IEnumerable<IEnumerable<string>> Export(string path)
{
string json = File.ReadAllText(path);
var document = JToken.Parse(json);
var data = new List<List<string>>();
.....
return data;
}
Note that there are better ways of parsing a file with json.net. For more info read this.
Related
I don't want to use Newtonsoft's Json.Net library. I'm avoiding any third-party dependencies if I can help it in this project.
If I have JSON that looks like this:
{
"has_more_items": false,
"items_html": "...",
"min_position": "1029839231781429248"
}
and I have a class that looks like this:
public class TwitterJson
{
bool hasMore { get; set; } // has_more_items
string rawText { get; set; } // items_html
string nextKey { get; set; } // min_position
}
and I have a JsonObject containing the above JSON:
JsonObject theJson = JsonObject.Parse(result);
How do I deserialize the JsonObject into my class? I've been trying to find a clear example of this, and everything I've found uses Json.Net.
I've been trying to find a clear example of this, and everything I've found uses Json.Net.
Because reinventing existing functionality is a waste of time especially when all the hard work has already been done for you.
If you insist on not using it then you will have to manually construct the object model based on the expected JSON.
For example, assuming publicly available properties
public class TwitterJson {
public bool hasMore { get; set; } // has_more_items
public string rawText { get; set; } // items_html
public string nextKey { get; set; } // min_position
}
Then parsing the above to the desired object model
JsonObject theJson = JsonObject.Parse(result);
var model = new TwitterJson {
hasMore = theJson.GetNamedBoolean("has_more_items"),
rawText = theJson.GetNamedString("items_html"),
nextKey = theJson.GetNamedString("min_position")
};
As mentioned by #Dimith, you need to decorate your class with [DataContract] and [DateMember], Please refer to below code which will convert your JSON into a given object.
// Deserialize a JSON string to a given object.
public static T ReadToObject<T>(string json) where T: class, new()
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
return ser.ReadObject(stream) as T;
}
}
Class:
[DataContract]
public class TwitterJson
{
[DataMember(Name = "has_more_items")]
bool hasMore { get; set; } // has_more_items
[DataMember(Name = "items_html")]
string rawText { get; set; } // items_html
[DataMember(Name = "min_position")]
string nextKey { get; set; } // min_position
}
Sample on how to use:
var result = "{\"has_more_items\": false, \"items_html\": \"...\",\"min_position\": \"1029839231781429248\"}";
var obj = ReadToObject<TwitterJson>(result);
You have to decorate your class with [DataContract] and [DataMember] attributes. Write the json into a memory stream and deserialize using DataContractJsonSerializer
Here is a more elaborated sample.
In addition to #Nkosi's answer below are some Comparisons between JSON.net and other alternatives:
JSON.Net vs DataContractJsonSerializer
JSON.Net vs Windows.Data.Json
Json string:
{"movies":[{"id":"1","title":"Sherlock"},{"id":"2","title":"The Matrix"}]}
C# class:
public class Movie {
public string title { get; set; }
}
C# converting json to c# list of Movie's:
JavaScriptSerializer jss = new JavaScriptSerializer();
List<Movie> movies = jss.Deserialize<List<Movie>>(jsonString);
My movies variable is ending up being an empty list with count = 0. Am I missing something?
Your c# class mapping doesn't match with json structure.
Solution :
class MovieCollection {
public IEnumerable<Movie> movies { get; set; }
}
class Movie {
public string title { get; set; }
}
class Program {
static void Main(string[] args)
{
string jsonString = #"{""movies"":[{""id"":""1"",""title"":""Sherlock""},{""id"":""2"",""title"":""The Matrix""}]}";
JavaScriptSerializer serializer = new JavaScriptSerializer();
MovieCollection collection = serializer.Deserialize<MovieCollection>(jsonString);
}
}
If you want to match the C# structure, you can change the JSON string like this:
{[{"id":"1","title":"Sherlock"},{"id":"2","title":"The Matrix"}]}
I'm new to c# and I tried to parse the JSON data from WSDL service.
Here is the code:
string cityjson = service.getcity();
/*
sample cityjson return
[{"City":"Alaminos","Province":"Pangasinan"},{"City":"Angeles","Province":"Pampanga"},{"City":"Antipolo","Province":"Rizal"}]
*/
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(cityjson)))
{
var serializer = new DataContractJsonSerializer(typeof(Location));
Location locs = (Location)serializer.ReadObject(ms);
Console.WriteLine(locs.Locations); // blank in console output.
}
and here is my datacontract code
[DataContract]
public class Location
{
[DataMember]
public String[] Locations;
}
when I do console.WriteLine(cityjson); it prints the whole json.
Your C# class is wrong.It should have two properties City and Province.And the json object is a List of Locations. And try to use JSON.Net to parse your json data.It's lightweight and easy to use.Also you could use available resources to convert json to C# types.
public class Location
{
public String City { get; set; }
public String Province { get; set; }
}
var t = "[{'City':'Alaminos','Province':'Pangasinan'},{'City':'Angeles','Province':'Pampanga'},{'City':'Antipolo','Province':'Rizal'}]";
var type = JsonConvert.DeserializeObject<List<Location>>(t);
use the namespace System.Web.Script.Serialization;
Rewrite your code like this
JavaScriptSerializer js = new JavaScriptSerializer();
Location locs = js.Deserialize<Location>(ms);
I am trying to post some data to my MVC 3 controller through a hidden text field that contains some JSON. I have that JSON passed in via string coursesList. Anyone have an idea why this is not working?
All I'm doing is making a byte [] out of the JSON string, writing it to a MemoryStream, and deserializing that stream -- or, attempting to. BookCourse bc always ends up with null properties.
Here's something like the JSON I would be using:
[{"coursesection":"1234","netlogon":"jsmith","label":"CRSE-1313 Generic Course Titling ~ Joe Smith"}]
And here's the object to be deserialized into:
using System.Runtime.Serialization;
namespace xxxx.Models
{
[DataContract]
public class BookCourse
{
[DataMember]
public string coursesection { get; set; }
[DataMember]
public string netlogon { get; set; }
[DataMember]
public string label { get; set; }
}
}
Finally, the controller action code to do it --
var byteArray = Encoding.ASCII.GetBytes(coursesList);
// Deserialize byte array to data type
var stream = new MemoryStream();
stream.Write(byteArray, 0, byteArray.Length);
var crs = new DataContractJsonSerializer(typeof(BookCourse));
stream.Position = 0;
// Read stream to object
ad.CourseSectionIDs = new List<int>();
try
{
var bc = (BookCourse) crs.ReadObject(stream);
while (bc.coursesection != null)
{
cs.AssociateCourseBook(bc.netlogon, bc.coursesection, ad.ISBN);
bc = (BookCourse)crs.ReadObject(stream);
}
}
catch (System.Runtime.Serialization.SerializationException e)
{
// Is this best practice for handling "none"?
}
Your JSON string represents a collection of BookCourse, not a single BookCourse. So adapt your code:
var serializer = new DataContractJsonSerializer(typeof(BookCourse[]));
and then:
var bookCourses = (BookCourse[])crs.ReadObject(stream);
or if you want to work with a single BookCourse you will need to change your JSON string and remove the wrapping square brackets which represent a collection.
Darin is correct, here is the change if you want to do it on a contract level.
[DataContract]
public class BookCourse
{
[DataMember]
public string coursesection { get; set; }
[DataMember]
public string netlogon { get; set; }
[DataMember]
public string label { get; set; }
}
[DataContract]
public class BookCourceCollection
{
[DataMember]
public List<BookCourse> Collection;
public static BookCourceCollection ReturnCollection(string jsonString)
{
MemoryStream ms;
BookCourceCollection collection;
using (ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(BookCourceCollection));
collection = ser.ReadObject(ms) as BookCourceCollection;
}
return collection;
}
}
Usage:
string jsonString = "Your JSON string from the front end";
var bookCourceObject = BookCourseCollection.ReturnCollection(jsonString);
foreach (BookCourse bookCourse in bookCourceObject.Collection)
{
cs.AssociateCourseBook(bookCourse.netlogon, bookCourse.coursesection, bookCourse.ISBN);
}
I have a json string and would like to make a DataTable from it.
How can I convert JSON to a DataTable in C#?
Update:
I have used Json.Net as per link provided here
and build 2 class to to handle json string as per below
public class JsonHelper
{
public List<User> userdata { get; set; }
}
public class User
{
public string name { get; set; }
public string id { get; set; }
public DateTime createdDate { get; set; }
}
and use following code to Deserialize
Newtonsoft.Json.JsonSerializer json = new Newtonsoft.Json.JsonSerializer();
json.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
json.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace;
json.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
json.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
StringReader sr = new StringReader(jsonstr);
Newtonsoft.Json.JsonTextReader reader = new JsonTextReader(sr);
object result = json.Deserialize(reader, typeof( JsonHelper));
reader.Close();
return result;
but getting following error
Cannot deserialize JSON array into type 'mynamespace+JsonHelper'.
What should be problem here , please help me to sort out this problem.
thanks.
This post by Rick Strahl may help you out. Under the covers he's using Newtonsoft's JSON.NET libraries to do the heavy lifting.