I have an object model that looks like this:
public MyObjectInJson { public long ObjectID {get;set;} public string ObjectInJson {get;set;} }
The property ObjectInJson
is an already serialized version an object that contains nested lists. For the moment, I’m serializing the list of MyObjectInJson
manually like this:
StringBuilder TheListBuilder = new StringBuilder(); TheListBuilder.Append("["); int TheCounter = 0; foreach (MyObjectInJson TheObject in TheList) { TheCounter++; TheListBuilder.Append(TheObject.ObjectInJson); if (TheCounter != TheList.Count()) { TheListBuilder.Append(","); } } TheListBuilder.Append("]"); return TheListBuilder.ToString();
I wonder if I can replace this sort of dangerous code with JavascriptSerializer
and get the same results.
How would I do this?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
If using .Net Core 3.0 or later;
Default to using the built in System.Text.Json
parser implementation.
e.g.
using System.Text.Json; var json = JsonSerializer.Serialize(aList);
alternatively, other, less mainstream options are available like Utf8Json parser and Jil: These may offer superior performance, if you really need it but, you will need to install their respective packages.
If stuck using .Net Core 2.2 or earlier;
Default to using Newtonsoft JSON.Net as your first choice JSON Parser.
e.g.
using Newtonsoft.Json; var json = JsonConvert.SerializeObject(aList);
you may need to install the package first.
PM> Install-Package Newtonsoft.Json
For more details see and upvote the answer that is the source of this information.
For reference only, this was the original answer, many years ago;
// you need to reference System.Web.Extensions using System.Web.Script.Serialization; var jsonSerialiser = new JavaScriptSerializer(); var json = jsonSerialiser.Serialize(aList);
Method 2
You can also use Json.NET. Just download it at http://james.newtonking.com/pages/json-net.aspx, extract the compressed file and add it as a reference.
Then just serialize the list (or whatever object you want) with the following:
using Newtonsoft.Json; string json = JsonConvert.SerializeObject(listTop10);
Update: you can also add it to your project via the NuGet Package Manager (Tools –> NuGet Package Manager –> Package Manager Console):
PM> Install-Package Newtonsoft.Json
Documentation: Serializing Collections
Method 3
There are two common ways of doing that with built-in JSON serializers:
-
JavaScriptSerializer
var serializer = new JavaScriptSerializer(); return serializer.Serialize(TheList);
-
DataContractJsonSerializer
var serializer = new DataContractJsonSerializer(TheList.GetType()); using (var stream = new MemoryStream()) { serializer.WriteObject(stream, TheList); using (var sr = new StreamReader(stream)) { return sr.ReadToEnd(); } }
Note, that this option requires definition of a data contract for your class:
[DataContract] public class MyObjectInJson { [DataMember] public long ObjectID {get;set;} [DataMember] public string ObjectInJson {get;set;} }
Method 4
public static string JSONSerialize<T>(T obj) { string retVal = String.Empty; using (MemoryStream ms = new MemoryStream()) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType()); serializer.WriteObject(ms, obj); var byteArray = ms.ToArray(); retVal = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length); } return retVal; }
Method 5
.NET already supports basic Json serialization through the System.Runtime.Serialization.Json namespace and the DataContractJsonSerializer class since version 3.5. As the name implies, DataContractJsonSerializer takes into account any data annotations you add to your objects to create the final Json output.
That can be handy if you already have annotated data classes that you want to serialize Json to a stream, as described in How To: Serialize and Deserialize JSON Data. There are limitations but it’s good enough and fast enough if you have basic needs and don’t want to add Yet Another Library to your project.
The following code serializea a list to the console output stream. As you see it is a bit more verbose than Json.NET and not type-safe (ie no generics)
var list = new List<string> {"a", "b", "c", "d"}; using(var output = Console.OpenStandardOutput()) { var writer = new DataContractJsonSerializer(typeof (List<string>)); writer.WriteObject(output,list); }
On the other hand, Json.NET provides much better control over how you generate Json. This will come in VERY handy when you have to map javascript-friendly names names to .NET classes, format dates to json etc.
Another option is ServiceStack.Text, part of the ServicStack … stack, which provides a set of very fast serializers for Json, JSV and CSV.
Method 6
If you’re doing this in the context of a asp.Net Core API action, the conversion to Json is done implicitly.
[HttpGet] public ActionResult Get() { return Ok(TheList); }
Method 7
building on an answer from another posting.. I’ve come up with a more generic way to build out a list, utilizing dynamic retrieval with Json.NET version 12.x
using Newtonsoft.Json; static class JsonObj { /// <summary> /// Deserializes a json file into an object list /// Author: Joseph Poirier 2/26/2019 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="fileName"></param> /// <returns></returns> public static List<T> DeSerializeObject<T>(string fileName) { List<T> objectOut = new List<T>(); if (string.IsNullOrEmpty(fileName)) { return objectOut; } try { // reading in full file as text string ss = File.ReadAllText(fileName); // went with <dynamic> over <T> or <List<T>> to avoid error.. // unexpected character at line 1 column 2 var output = JsonConvert.DeserializeObject<dynamic>(ss); foreach (var Record in output) { foreach (T data in Record) { objectOut.Add(data); } } } catch (Exception ex) { //Log exception here Console.Write(ex.Message); } return objectOut; } }
call to process
{ string fname = "../../Names.json"; // <- your json file path // for alternate types replace string with custom class below List<string> jsonFile = JsonObj.DeSerializeObject<string>(fname); }
or this call to process
{ string fname = "../../Names.json"; // <- your json file path // for alternate types replace string with custom class below List<string> jsonFile = new List<string>(); jsonFile.AddRange(JsonObj.DeSerializeObject<string>(fname)); }
Method 8
using System; using System.Text.Json; using System.Collections.Generic; public class Program { public static void Main() { List<ErrorDetail> aList = new List<ErrorDetail>(); ErrorDetail a = new ErrorDetail{ ColumnName="aaa", ErrorText="abbbb"}; ErrorDetail c = new ErrorDetail{ ColumnName="ccc", ErrorText="cccc"}; ErrorDetail b = new ErrorDetail{ ColumnName="ccc", ErrorText="cccc"}; aList.Add(a); aList.Add(b); aList.Add(c); var json = JsonSerializer.Serialize(aList); Console.WriteLine(json); } public class ErrorDetail { public string ColumnName { get; set; } public string ErrorText { get; set; } } }
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0