179

I'm attempting to use the following code to serialize an anonymous type to JSON:

var serializer = new DataContractJsonSerializer(thing.GetType());
var ms = new MemoryStream();
serializer.WriteObject(ms, thing);
var json = Encoding.Default.GetString(ms.ToArray()); 

However, I get the following exception when this is executed:

Type '<>f__AnonymousType1`3[System.Int32,System.Int32,System.Object[]]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.

I can't apply attributes to an anonymous type (as far as I know). Is there another way to do this serialization or am I missing something?

Dariusz Woźniak
  • 9,640
  • 6
  • 60
  • 73
JC Grubbs
  • 39,191
  • 28
  • 66
  • 75

9 Answers9

162

Try the JavaScriptSerializer instead of the DataContractJsonSerializer

JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);
Fenton
  • 241,084
  • 71
  • 387
  • 401
Nick Berardi
  • 54,393
  • 15
  • 113
  • 135
92

As others have mentioned, Newtonsoft JSON.NET is a good option. Here is a specific example for simple JSON serialization:

return JsonConvert.SerializeObject(
    new
    {
       DataElement1,
       SomethingElse
    });

I have found it to be a very flexible, versatile library.

Matthew Nichols
  • 4,866
  • 4
  • 41
  • 48
18

You can try my ServiceStack JsonSerializer it's the fastest .NET JSON serializer at the moment. It supports serializing DataContract's, Any POCO Type, Interfaces, Late-bound objects including anonymous types, etc.

Basic Example

var customer = new Customer { Name="Joe Bloggs", Age=31 };
var json = customer.ToJson();
var fromJson = json.FromJson<Customer>(); 

Note: Only use Microsofts JavaScriptSerializer if performance is not important to you as I've had to leave it out of my benchmarks since its up to 40x-100x slower than the other JSON serializers.

mythz
  • 141,670
  • 29
  • 246
  • 390
  • 8
    I am using the MS JavaScriptSerializer on the MVC3 stack to serialize objects with small amounts of data. It's pretty fast in these cases, taking less than a millisecond to do what I need. The DB query itself takes 50x-100x longer, so it's not really a significant bottleneck in my situation. – Brian Oct 15 '12 at 14:00
  • 2
    Premature optimization is a... Well you know. – Mathias Lykkegaard Lorenzen Aug 30 '14 at 13:16
  • 4
    "fastest .NET JSON serializer" link is 404ing! Plus, this answer is over 5 1/2 years old. Do you have an update on performance of various .NET JSON serializers? – ErikE Apr 01 '16 at 08:55
16

For those checking this around the year 2020:

Microsoft's System.Text.Json namespace is the new king in town. In terms of performance, it is the best as far as I can tell:

var model = new Model
{
    Name = "Test Name",
    Age = 5
};

string json = JsonSerializer.Serialize(model);

As some others have mentioned, NewtonSoft.Json is a very nice library as well.

Dharman
  • 30,962
  • 25
  • 85
  • 135
SmartE
  • 523
  • 5
  • 11
12

The fastest way I found was this:

var obj = new {Id = thing.Id, Name = thing.Name, Age = 30};
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(obj);

Namespace: System.Web.Script.Serialization.JavaScriptSerializer

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
i31nGo
  • 1,422
  • 15
  • 11
  • 2
    And for deserialization: . . dynamic myObject = JsonConvert.DeserializeObject(output); . . reference: Newtonsoft.json.dll – i31nGo May 23 '14 at 10:13
11

Please note this is from 2008. Today I would argue that the serializer should be built in and that you can probably use swagger + attributes to inform consumers about your endpoint and return data.


Iwould argue that you shouldn't be serializing an anonymous type. I know the temptation here; you want to quickly generate some throw-away types that are just going to be used in a loosely type environment aka Javascript in the browser. Still, I would create an actual type and decorate it as Serializable. Then you can strongly type your web methods. While this doesn't matter one iota for Javascript, it does add some self-documentation to the method. Any reasonably experienced programmer will be able to look at the function signature and say, "Oh, this is type Foo! I know how that should look in JSON."

Having said that, you might try JSON.Net to do the serialization. I have no idea if it will work

Jason Jackson
  • 17,016
  • 8
  • 49
  • 74
  • 3
    JSON.Net works just fine. I would argue that you shouldn't :), I think it's pretty legitimate in many cases. – aprilchild Dec 01 '08 at 19:56
  • 2
    After seeing the "throw away" types being used in MVC I can see some compelling uses. I think it is a very handy tool to have in your .Net tool box. – Matthew Whited Jun 07 '09 at 03:21
  • 13
    This is a point I have also softened on, especially in the case of consumption-only types. But if the object is making a return trip to the server, or is used in more than one location, I still believe that creating a type will result in fewer problems. – Jason Jackson Jun 07 '09 at 16:01
  • DataContract style de-serialization doesn't handle polymorphic types well. You have to write your own de-serializer. Too much code maintenance. – micahhoover Jan 12 '15 at 16:05
  • A use case where serializing anonymous types is useful is unit tests for web APIs. – howcheng Feb 24 '16 at 00:39
  • Another use case, I'm trying to make a charting web service function where you just send it JSON data and a config structure in the same send, telling it what column is X and what column is Y... Since I know nothing about the data going in to the API, strong typing is foobar. – Dan Chase Jan 31 '19 at 17:21
10

You could use Newtonsoft.Json.

var warningJSON = JsonConvert.SerializeObject(new {
               warningMessage = "You have been warned..."
            });

A faster alternative with Microsofts' new library on System.Text.Json

var warningJSON = JsonSerializer.Serialize(new {
               warningMessage = "You have been warned..."
            });
Ahmet Arslan
  • 5,380
  • 2
  • 33
  • 35
1

Assuming you are using this for a web service, you can just apply the following attribute to the class:

[System.Web.Script.Services.ScriptService]

Then the following attribute to each method that should return Json:

[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

And set the return type for the methods to be "object"

Paul
  • 3,125
  • 2
  • 24
  • 21
  • For a standard ASP web service [ScriptMethod(ResponseFormat = ResponseFormat.Json)] is not needed on the method, [WebMethod] will do. Also you should not set the return type to object, it can and should be strongly typed with a non-complex (i.e. can be serialized) type. – row1 Mar 08 '10 at 08:42
-2
public static class JsonSerializer
{
    public static string Serialize<T>(this T data)
    {
        try
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            var stream = new MemoryStream();
            serializer.WriteObject(stream, data);
            string jsonData = Encoding.UTF8.GetString(stream.ToArray(), 0, (int)stream.Length);
            stream.Close();
            return jsonData;
        }
        catch
        {
            return "";
        }
    }
    public static T Deserialize<T>(this string jsonData)
    {
        try
        {
            DataContractJsonSerializer slzr = new DataContractJsonSerializer(typeof(T));
            var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonData));
            T data = (T)slzr.ReadObject(stream);
            stream.Close();
            return data;
        }
        catch
        {
            return default(T);
        }
    }
}
harryovers
  • 3,087
  • 2
  • 34
  • 56