如何将C#匿名类型序列化为JSON字符串?

How do I serialize a C# anonymous type to a JSON string?

我正试图使用以下代码将匿名类型序列化为JSON:

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

但是,在执行此操作时,我会得到以下异常:

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.

我不能将属性应用于匿名类型(据我所知)。有没有其他方法来做这个序列化,或者我遗漏了什么?


尝试javascriptserializer而不是datacontractjsonserializer

1
2
JavaScriptSerializer serializer = new JavaScriptSerializer();
var output = serializer.Serialize(your_anon_object);


正如其他人提到的,newtonsoft json.net是一个不错的选择。下面是简单JSON序列化的具体示例:

1
2
3
4
5
6
return JsonConvert.SerializeObject(
    new
    {
       DataElement1,
       SomethingElse
    });

我发现它是一个非常灵活的,多功能的图书馆。


你可以试试我的ServiceStack JSonserializer,它是目前速度最快的.NET JSON序列化程序。它支持序列化数据合同、任何POCO类型、接口、后期绑定对象(包括匿名类型)等。

基本实例

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

注意:只有在性能对您不重要的情况下才使用MicrosoftsJavaScriptSerializer,因为它比其他JSON序列化程序慢40到100倍,所以我不得不将其排除在基准之外。


请注意,这是从2008年开始的。今天我认为序列化程序应该是内置的,您可以使用swager+属性来通知消费者您的端点和返回数据。

我认为你不应该序列化一个匿名类型。我知道这里的诱惑;您希望快速生成一些丢弃的类型,这些类型将在松散的类型环境中使用,也就是浏览器中的javascript。不过,我还是会创建一个实际的类型并将其装饰为可序列化的。然后您可以强烈地键入Web方法。虽然对于javascript来说这一点都不重要,但它确实为该方法添加了一些自文档。任何有经验的程序员都可以查看函数签名并说:"哦,这是foo类型!我知道在JSON中应该怎么看。"

这么说之后,您可以尝试json.net来进行序列化。我不知道它能不能用


我发现最快的方法是:

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

命名空间:system.web.script.serialization.javascriptserializer


假设您将此项用于Web服务,则只需将以下属性应用于类:

1
[System.Web.Script.Services.ScriptService]

然后对每个应该返回JSON的方法使用以下属性:

1
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

并将方法的返回类型设置为"对象"


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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);
        }
    }
}