242

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?

1

9 Answers 9

452

If using .Net 6.0 or later;

Default to using the built in System.Text.Json parser implementation with Source Generation. Its a little more typing and compiling but, is more efficient at runtime.

The "easier to code" option below, still works but, less efficiently because it uses Reflection at runtime. The new method has some intentional, by design limitations. If you can't change your model to avoid those, the Reflection based method remains available.

e.g.

using System.Text.Json;
using System.Text.Json.Serialization;

var aList = new List<MyObjectInJson>
{
    new(1, "1"),
    new(2, "2")
};

var json = JsonSerializer.Serialize(aList, Context.Default.ListMyObjectInJson);
Console.WriteLine(json);

return;

public record MyObjectInJson
(
    long ObjectId,
    string ObjectInJson
);

[JsonSerializable(typeof(List<MyObjectInJson>))]
internal partial class Context : JsonSerializerContext
{
}

If using .Net Core 3.0 to .Net 5.0, it is time to upgrade;

Default to using the built in System.Text.Json parser implementation.

e.g.

using System.Text.Json;

var json = JsonSerializer.Serialize(aList);

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);
9
  • 1
    ah ok, it ALSO serializes lists of objects and not just objects themselves. Thanks.
    – frenchie
    Commented Feb 2, 2012 at 10:48
  • doesen't like cyclical relationships but that is not a problem here
    – Jodrell
    Commented Feb 2, 2012 at 10:53
  • 13
    Note that this namespace is cunningly tucked-away in System.Web.Extensions. Once you add that as a reference, the solution works brilliantly! Commented May 9, 2013 at 16:25
  • 1
    I see your edited answer and really wish I had an updated example. Commented Apr 3, 2015 at 21:04
  • 1
    @IamNumber5 already provided in the other answer. I extended my answer anyway.
    – Jodrell
    Commented Jun 2, 2015 at 9:38
123

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

0
13

There are two common ways of doing that with built-in JSON serializers:

  1. JavaScriptSerializer

    var serializer = new JavaScriptSerializer();
    return serializer.Serialize(TheList);
    
  2. 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;}
    }
    
6
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;
        }
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.

1

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));
}
1

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);
}
3
  • Its not serializing in my case
    – Gilbert
    Commented Aug 5, 2021 at 21:01
  • @Gilboot what is it doing instead? Commented Aug 6, 2021 at 12:47
  • Its ok, I had left out { get; set; } on the property. I am a beginner C# programmer. Thanks anyway
    – Gilbert
    Commented Aug 6, 2021 at 21:42
1
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; }
    
    
    
    
        }
    }
1
  • [{"ColumnName":"aaa","ErrorText":"abbbb"},{"ColumnName":"ccc","ErrorText":"cccc"},{"ColumnName":"ccc","ErrorText":"cccc"}] Commented Jul 21, 2021 at 8:40
1

I tried the other answers here to serialize parameters for a POST request, but my backend did not like the fact that I was sending up a string version of my array. I did not want to have to always check if the type of a parameter is a string and convert it to an array.

I'm using Json.NET (which is now built into C#), and I convert my List to an array and let the converter handle the rest.

public class MyObjectInJson 
{
    public long ID;
    public OtherObject[] array;
}

You can convert your List into an array using list.ToArray();

And then finally using the JsonConvert, you can turn the entire object into a string:

string jsonString = JsonConvert.SerializeObject(objectInJson);

Hope this helps someone else.

Not the answer you're looking for? Browse other questions tagged or ask your own question.