Làm cách nào để tôi tuần tự hóa một loại ẩn danh C # thành một chuỗi JSON?


162

Tôi đang cố sử dụng đoạn mã sau để tuần tự hóa một loại ẩn danh thành JSON:

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

Tuy nhiên, tôi nhận được ngoại lệ sau khi điều này được thực thi:

Loại '<> f__AnonymousType1`3 [System.Int32, System.Int32, System.Object []]' không thể được nối tiếp. Xem xét đánh dấu nó bằng thuộc tính DataContractAttribution và đánh dấu tất cả các thành viên mà bạn muốn tuần tự hóa bằng thuộc tính DataMemberAttribution. Xem tài liệu Microsoft .NET Framework để biết các loại được hỗ trợ khác.

Tôi không thể áp dụng các thuộc tính cho một loại ẩn danh (theo như tôi biết). Có cách nào khác để thực hiện việc tuần tự hóa này hay tôi đang thiếu một cái gì đó?

Câu trả lời:


159

Hãy dùng thử JavaScriptSerializer thay vì DataContractJsonSerializer

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

17
Theo dõi, có vẻ như nó đã bị từ chối trong SP1.
Biswanath

7
đối với một cái gì đó quá lỗi thời, nó dường như được sử dụng trong nhiều khung công tác mới của Microsoft, bao gồm cả MVC. aspnet.codeplex.com/SourceControl/changeset/view/21528#266491
Nick Berardi

1
Làm cách nào để bao gồm dự án ia non-asp.net này (ứng dụng bảng điều khiển)?
Alxandr

4
@Alxandr: Bạn sẽ cần tham khảo System.Web.Extensions.dllvà thêm một using System.Web.Script.Serialization;tuyên bố.
Randomguy

1
Vấn đề @randomgui là loại đầu ra dự án được đặt thành hồ sơ khách hàng.
Alxandr

75

Như những người khác đã đề cập, Newtonsoft JSON.NET là một lựa chọn tốt. Dưới đây là một ví dụ cụ thể cho việc tuần tự hóa JSON đơn giản:

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

Tôi đã tìm thấy nó là một thư viện rất linh hoạt, linh hoạt.


14

Bạn có thể dùng thử ServiceStack JsonSerializer, đây là trình tuần tự hóa .NET JSON nhanh nhất vào lúc này. Nó hỗ trợ tuần tự hóa DataContract, Bất kỳ loại POCO, Giao diện, các đối tượng bị ràng buộc muộn bao gồm các loại ẩn danh, v.v.

Ví dụ cơ bản

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

Lưu ý: Chỉ sử dụng microsofts JavaScriptSerializer nếu hiệu suất không quan trọng đối với bạn vì tôi phải rời khỏi điểm chuẩn của mình vì tốc độ của nó chậm hơn tới 40 lần so với các trình sắp xếp JSON khác.


7
Tôi đang sử dụng MS JavaScriptSerializer trên ngăn xếp MVC3 để tuần tự hóa các đối tượng với một lượng nhỏ dữ liệu. Nó khá nhanh trong những trường hợp này, mất ít hơn một phần nghìn giây để làm những gì tôi cần. Bản thân truy vấn DB mất 50x-100x, do đó, đây không thực sự là một nút cổ chai đáng kể trong tình huống của tôi.
Brian

2
Tối ưu hóa sớm là một ... Bạn biết đấy.
Mathias Lykkegaard Lorenzen

1
Liên kết "tuần tự hóa .NET JSON nhanh nhất" là 404ing! Thêm vào đó, câu trả lời này là hơn 5 năm rưỡi. Bạn có bản cập nhật về hiệu suất của các bộ nối tiếp .NET JSON khác nhau không?
ErikE

11

Xin lưu ý đây là từ năm 2008. Hôm nay tôi cho rằng nên tích hợp bộ nối tiếp và bạn có thể sử dụng các thuộc tính swagger + để thông báo cho người tiêu dùng về điểm cuối và dữ liệu trả về của bạn.


Iwould cho rằng bạn không nên đăng một loại ẩn danh . Tôi biết sự cám dỗ ở đây; bạn muốn nhanh chóng tạo ra một số loại bỏ đi sẽ được sử dụng trong môi trường loại lỏng lẻo hay còn gọi là Javascript trong trình duyệt. Tuy nhiên, tôi sẽ tạo ra một loại thực tế và trang trí nó như là Nối tiếp. Sau đó, bạn có thể gõ mạnh các phương pháp web của bạn. Mặc dù điều này không thành vấn đề với một iota cho Javascript, nhưng nó lại thêm một số tài liệu tự vào phương thức. Bất kỳ lập trình viên có kinh nghiệm hợp lý nào cũng sẽ có thể nhìn vào chữ ký hàm và nói, "Ồ, đây là loại Foo! Tôi biết nó nên trông như thế nào trong JSON."

Có nói rằng, bạn có thể thử JSON.Net để thực hiện tuần tự hóa. Tôi không biết nó có hoạt động không


3
JSON.Net hoạt động tốt. Tôi sẽ tranh luận rằng bạn không nên :), tôi nghĩ rằng nó khá hợp pháp trong nhiều trường hợp.
aprilchild

2
Sau khi thấy các kiểu "vứt đi" đang được sử dụng trong MVC, tôi có thể thấy một số cách sử dụng hấp dẫn. Tôi nghĩ rằng nó là một công cụ rất tiện dụng để có trong hộp công cụ .Net của bạn.
Matthew Whited

12
Đây là một điểm tôi cũng đã làm mềm, đặc biệt trong trường hợp các loại chỉ tiêu thụ. Nhưng nếu đối tượng đang thực hiện một chuyến trở về máy chủ hoặc được sử dụng ở nhiều hơn một địa điểm, tôi vẫn tin rằng việc tạo một loại sẽ dẫn đến ít vấn đề hơn.
Jason Jackson

Khử tuần tự kiểu DataContract không xử lý tốt các kiểu đa hình. Bạn phải viết de-serializer của riêng bạn. Bảo trì mã quá nhiều.
micahhoover

Một trường hợp sử dụng trong đó tuần tự hóa các loại ẩn danh là hữu ích là các thử nghiệm đơn vị cho các API web.
howcheng

9

Cách nhanh nhất tôi tìm thấy là đây:

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

Không gian tên: System.Web.Script.Serialization.JavaScriptSerializer


2
Và để khử lưu huỳnh :. . động myObject = JsonConvert.DeserializeObject <động> (đầu ra); . . tham khảo: Newtonsoft.json.dll
i31nGo

2

Bạn có thể sử dụng Newtonsoft.Json.

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

1

Giả sử bạn đang sử dụng điều này cho một dịch vụ web, bạn chỉ có thể áp dụng thuộc tính sau cho lớp:

[System.Web.Script.Services.ScriptService]

Sau đó, thuộc tính sau cho mỗi phương thức sẽ trả về Json:

[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

Và đặt kiểu trả về cho các phương thức là "đối tượng"


Đối với dịch vụ web ASP tiêu chuẩn [ScriptMethod (FeedbackFormat = FeedbackFormat.Json)] không cần thiết trên phương thức, [WebMethod] sẽ làm. Ngoài ra, bạn không nên đặt loại trả về thành đối tượng, nó có thể và nên được gõ mạnh với loại không phức tạp (nghĩa là có thể được tuần tự hóa).
hàng1

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

Điều này không tuần tự hóa các loại ẩn danh theo câu hỏi
Mark Sowul
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.