.NET WebAPI Serialization k_BackingField Nastiness


86

Khi tôi tuần tự như sau:

[Serializable]
public class Error
{

    public string Status { get; set; }
    public string Message { get; set; }
    public string ErrorReferenceCode { get; set; }
    public List<FriendlyError> Errors { get; set; }
}

Tôi nhận được mớ hỗn độn kinh tởm này:

<ErrorRootOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance"   xmlns="http://schemas.datacontract.org/2004/07/Printmee.Api">
<_x003C_Errors_x003E_k__BackingField>
An exception has occurred. Please contact printmee support
</_x003C_Errors_x003E_k__BackingField>
<_x003C_LookupCode_x003E_k__BackingField>988232ec-6bc9-48f3-8116-7ff7c71302dd</_x003C_LookupCode_x003E_k__BackingField>
</ErrorRootOfstring>

Đưa cái gì? Làm thế nào tôi có thể làm cho nó đẹp? Các phản hồi JSON cũng chứa k_BackingField


Câu trả lời:


126

Theo mặc định, bạn không cần sử dụng [Serializable]cũng như không [DataContract]làm việc với API Web.

Chỉ cần giữ nguyên mô hình của bạn và API Web sẽ tuần tự hóa tất cả các thuộc tính công khai cho bạn.

Chỉ khi bạn muốn có nhiều quyền kiểm soát hơn về những gì được bao gồm, thì bạn hãy trang trí lớp của mình [DataContract]và các thuộc tính được bao gồm [DataMember](vì cả DCS và JSON.NET đều đáp ứng các thuộc tính này).

Nếu vì lý do nào đó, bạn cần [Serializable]lớp của mình (tức là bạn đang tuần tự hóa nó vào luồng bộ nhớ vì một lý do nào đó, thực hiện các bản sao sâu, v.v.), thì bạn phải sử dụng cả hai thuộc tính kết hợp để ngăn các tên trường sao lưu:

[Serializable]
[DataContract]
public class Error
{
    [DataMember]
    public string Status { get; set; }
    [DataMember]
    public string Message { get; set; }
    [DataMember]
    public string ErrorReferenceCode { get; set; }
    [DataMember]
    public List<FriendlyError> Errors { get; set; }
}

6
Vậy là xong-- Tôi chỉ cần xóa [Có thể nối tiếp]. Cảm ơn.
Micah

Cảm ơn Filip, phải giữ các thuộc tính vì bộ nhớ cache .. BTW, tôi là một người hâm mộ cuồng nhiệt blog của bạn .. hãy tiếp tục phát triển!
Stephen Patten vào

20
Thật là khủng khiếp. Tại sao Microsoft EVER không thể làm bất cứ điều gì chính xác khi nói đến tuần tự hóa?
Chris Marisic,

Có một giải pháp tổng quát hơn, như tôi trình bày trong câu trả lời của riêng tôi bên dưới.
JotaBe

Có lẽ vấn đề với tuần tự hóa là định nghĩa "đúng", mọi người đều cần dữ liệu theo cách của họ.
Luiz Felipe

94

Có một giải pháp tổng quát hơn: bạn có thể cấu hình Json Serializer để bỏ qua [Serializable]thuộc tính, để bạn không phải thay đổi các thuộc tính trong các lớp của mình.

Bạn nên thực hiện thay đổi cấu hình này khi khởi động ứng dụng, tức là trong Application_Startsự kiện Global.asax :

var serializerSettings =
  GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
var contractResolver =
  (DefaultContractResolver)serializerSettings.ContractResolver;
contractResolver.IgnoreSerializableAttribute = true;

Bạn cũng có thể thực hiện các thay đổi khác đối với tuần tự hóa Json, như chỉ định định dạng để tuần tự hóa ngày tháng và nhiều thứ khác.

Điều này sẽ chỉ áp dụng cho tuần tự hóa JSON API Web. Các tuần tự hóa khác trong ứng dụng (tuần tự hóa API Web API, MVC JsonResult ...) sẽ không bị ảnh hưởng bởi cài đặt này.


4
Tôi thích giải pháp này hơn nhiều so với việc thêm các thuộc tính [DataContract] và [DataMember] ở khắp mọi nơi. Cảm ơn bạn!!
Đánh dấu tốt

1
Không phải là thứ bạn nên sử dụng mọi lúc, nhưng đây là một mẹo nhỏ. Loại xà beng giúp bạn vượt qua những tình huống lộn xộn mà bạn không có đủ điều kiện để thay đổi mô hình hoặc cấu trúc lại cơ sở mã một cách chuyên sâu.
uygar.raf

Bạn nói đúng rằng đây không phải là cách tốt nhất để làm điều đó. Tuy nhiên, trong một số trường hợp, việc tái cấu trúc nó không chỉ là điều xa xỉ mà còn không khả thi chút nào. Ví dụ: nếu cơ sở mã sử dụng WCF hoặc XML Serialization, thì nó yêu cầu các thuộc tính Data Contract hoặc XML serialization. Bạn không thể thay đổi điều đó. May mắn thay JSON.NET rất mạnh mẽ: nó hỗ trợ Hợp đồng dữ liệu, tuần tự hóa XML và các thuộc tính riêng của nó và bạn có thể kiểm soát cách nó sử dụng chúng để tuần tự hóa hoặc thậm chí hoàn toàn bỏ qua chúng. Và bạn thậm chí có thể thêm phần triển khai của riêng mình. Tất nhiên, tôi thích giữ sạch sẽ không có thuộc tính.
JotaBe

Đây là cách nó sẽ hoạt động theo mặc định! Tại sao chúng ta lại bỏ qua những thứ vô nghĩa của backingfield trong luồng được đăng nhiều kỳ của mình?
Byron Whitlock

1
Nếu bạn đang sử dụng web api và đang nhắm mục tiêu phiên bản 4 của khung .net thì bạn sẽ cần cập nhật gói Netwonsoft.Json để điều này hoạt động, tức là Update-Package Newtonsoft.Json.
pblack


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.