187

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?

0

9 Answers 9

162

Try the JavaScriptSerializer instead of the DataContractJsonSerializer

JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);
Sign up to request clarification or add additional context in comments.

8 Comments

Trackback, it seems it was de-deprecated in SP1.
for something so obsolute, it appears to be getting used in many new Microsoft frameworks, including MVC. aspnet.codeplex.com/SourceControl/changeset/view/21528#266491
How do I include this i a non-asp.net project (console application)?
@Alxandr: You would need to reference System.Web.Extensions.dll and add a using System.Web.Script.Serialization; statement.
@randomgui problem was project output type was set to client-profile.
|
98

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.

Comments

21

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.

Comments

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.

3 Comments

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.
Premature optimization is a... Well you know.
"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?
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

1 Comment

And for deserialization: . . dynamic myObject = JsonConvert.DeserializeObject<dynamic>(output); . . reference: Newtonsoft.json.dll
12

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..."
            });

Comments

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

6 Comments

JSON.Net works just fine. I would argue that you shouldn't :), I think it's pretty legitimate in many cases.
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.
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.
DataContract style de-serialization doesn't handle polymorphic types well. You have to write your own de-serializer. Too much code maintenance.
A use case where serializing anonymous types is useful is unit tests for web APIs.
|
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"

1 Comment

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

1 Comment

This does not serialize anonymous types as per the question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.