Cách xóa k__BackingField khỏi json khi Deserialize


104

Tôi nhận được k_BackingField trong json trả về của mình sau khi tuần tự hóa tệp xml thành đối tượng .net c #.

Tôi đã thêm thuộc tính DataContract và DataMember vào đối tượng .net c # nhưng sau đó tôi không nhận được gì trên json, client end.

[XmlRoot("person")]
[Serializable]
public class LinkedIn
{
    [XmlElement("id")]
    public string ID { get; set; }

    [XmlElement("industry")]
    public string Industry { get; set; }

    [XmlElement("first-name")]
    public string FirstName { get; set; }

    [XmlElement("last-name")]
    public string LastName { get; set; }
    [XmlElement("headline")]
}

Ví dụ về json được trả về:

home: Object
<FirstName>k__BackingField: "Storefront"
<LastName>k__BackingField: "Doors"

Câu trả lời:


45

Cú pháp Thuộc tính tự động thực sự không được khuyến khích nếu lớp có thể được sử dụng trong tuần tự hóa. Lý do là trường hỗ trợ được tạo ra bởi trình biên dịch, có thể khác nhau mỗi khi mã được biên dịch. Điều này có thể gây ra vấn đề không tương thích ngay cả khi không có thay đổi nào đối với lớp (chỉ cần biên dịch lại mã).

Tôi nghĩ rằng việc áp dụng thuộc tính DataMember sẽ khắc phục được sự cố trong trường hợp này. Nhưng tôi khuyên bạn nên sử dụng cú pháp thuộc tính đầy đủ, nếu lớp cần được sử dụng trong tuần tự hóa.


Lol, thực hiện các phiên bản dài và nó thiết lập các lĩnh vực tư nhân vào client.home: Object _fName: "cửa hàng" _headline: "Giám đốc điều hành tại StorefrontDoors.NET" _id: "" _industry: ""
Điền Stack là gì Tôi DO

21
thêm ký tự dữ liệu đó vào đầu lớp và ký tự dữ liệu vào từng thuộc tính mà tôi quan tâm đã hoạt động.
Điền vào ngăn xếp là những gì tôi làm

3
@ AlumCloud.Com +1 cho [DataContract] và [DataMember]. Đừng quên thêm: System.Runtime.Serialization
Ian Newland

109

Xóa [Serializable]khỏi lớp học của bạn


2
Bây giờ tôi đang tự hỏi tại sao tôi nghĩ rằng tôi cần [Serializable] ngay từ đầu. Quá trình tuần tự hóa Xml của tôi hoạt động mà không có và JSON hoạt động mà không có nó.
Rhyous

11
Điều này không hoạt động với Dịch vụ WCF. Khi trả lại một tải trọng bằng cách sử dụng các dịch vụ RESTful, điều này không mang lại bất kỳ dữ liệu nào nếu bạn xóa [Serializable]. Thêm System.Runtime.Serialization và sử dụng [DataContract] cho lớp, [DataMember] cho các thuộc tính.
Ian Newland

Câu trả lời VÀ nhận xét Ian này dường như bao gồm cả hai trường hợp. Tới WCF hay không WCF, đó là câu hỏi.
granadaCoder,

1
@Rhyous - trong Web API, bạn không cần [Serializable], bởi vì Web API được thiết lập với giả định rằng bạn sẽ tuần tự hóa và trả về các đối tượng của mình (vì về cơ bản đó là toàn bộ ý tưởng) - trong các ứng dụng C # khác, bạn thường cần Serializable để phân biệt các đối tượng có thể serializable
Jon Story

Cảm ơn bạn, tôi đã gặp khó khăn [Serializable], vì vậy việc thêm các trường hỗ trợ đã giúp ích.
ohmusama

59

Bộ tuần tự WebApi mặc định sẽ thêm cú pháp "__BackingField:" đó vào thuộc tính tự động c #. Thêm cái này vào WebConfig của bạn trong App_Start để có được json trông gọn gàng hơn mà bạn có thể đang tìm kiếm.

using Newtonsoft.Json;
...

config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();

3
Điều này đã khắc phục sự cố. Tôi nghĩ rằng các thuộc tính ô tô là sạch sẽ. Sử dụng trường hỗ trợ ở khắp mọi nơi có vẻ ngu ngốc. và giới thiệu nhiều lộn xộn và đôi khi nhầm lẫn.
Romesh D. Niriella

Điều này đã làm việc cho tôi. Trong trường hợp của tôi, tôi có một lớp hiện có đã được sử dụng bởi WCF và ASMX webservices, vì vậy tôi không thể thay đổi nó cho dự án WebAPI mới của mình.
samiup

4
Câu hỏi đặt ra là tại sao trên trái đất, bộ tuần tự WebApi sẽ thêm "__BackingField:" đó theo mặc định?
Teoman shipahi 19/1017

giải pháp tốt. trong trường hợp của tôi, tôi cần sử dụng lưu [Serializable] vào memcache. Serializable là bắt buộc.
Bình Nguyễn Quang

2
Tôi sẽ làm gì nếu không có StackOverflow? Cảm ơn.
camainc

35

Chúng tôi có một số đối tượng được đánh dấu là [Serializable]chúng có thể được tuần tự hóa bằng các phương pháp truyền thống, nhưng chúng tôi cần phải tuần tự hóa rõ ràng trong JSON để sử dụng với API Web. Đặt IgnoreSerializableAttributethành truesẽ ngăn Newtonsoft.Json hoạt động giống như các trình tuần tự của Microsoft và thay vào đó nó sẽ chỉ tuần tự hóa các thuộc tính chung.

TLDR: Thêm cái này vào WebApiConfig.cs:

((Newtonsoft.Json.Serialization.DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;

Người kiểm duyệt: Thay vì xóa một câu trả lời thực sự tốt cho một câu hỏi đã được hỏi nhiều lần, hãy xóa câu hỏi trùng lặp. Đây là một câu trả lời hợp lệ cho một câu hỏi hợp lệ.


3
Đây phải là câu trả lời đúng. Loại bỏ Serialization hoặc sử dụng các thuộc tính datacontract và datamember không phải lúc nào cũng là giải pháp chính xác.
Houssam Hamdan

Nhiều người trong chúng ta không, bao gồm cả OP, sử dụng Webapi hoặc MVVM hoặc những gì các bạn đang sử dụng. App_start và webapiconfig là gì khi tôi có dịch vụ WCF xà phòng bình thường với service.svc?
Christian

10

Cách đơn giản và dễ dàng để hiển thị dữ liệu Chúng ta cần hiển thị dữ liệu trong đối tượng ở định dạng dễ đọc và nhất quán


Trước tiên, hãy xóa [Serializable]

    [Serializable]

bây giờ hãy thêm [DataContract] trong lớp và [DataMember] cho thuộc tính như ví dụ dưới đây

[DataContract]
public class UserDiscretion : UserReport
{
    [DataMember]
    public String DiscretionCode { get; set; }
    public String DiscretionDescription { get; set; }
}

Hy vọng điều này giúp đỡ
Cảm ơn.


1
Nếu sử dụng API Web, bạn không cần phải thêm các thuộc tính DataContract và DataMember - chỉ cần trả về đối tượng và nó sẽ được tuần tự hóa.
Jon Story

Nếu bất kỳ ai bắt đầu phát triển từ đầu thì sẽ thật tuyệt khi sử dụng API Web cung cấp kiểu trả về Đối tượng sẽ không yêu cầu bất kỳ kiểu truyền kiểu nào để hiển thị cho khách hàng. Nhưng đối với câu hỏi của @ AlumCloud.com, nếu anh ấy đang ở trong ứng dụng hiện có thì giải pháp cho vấn đề của anh ấy sẽ là Trước tiên hãy xóa [Serializable] sau đó thêm [DataContract] trong lớp và [DataMember] cho thuộc tính như bên dưới như được đề xuất
Nagendra Upwanshi

1
Điều này tạo thêm một lượng lớn "nhiễu" cho các lớp của bạn và về cơ bản là không cần thiết (xem tất cả các nhận xét khác). Tuy nhiên, nếu ai đó cảm thấy cần thực sự làm điều này, tôi khuyên bạn nên sử dụng một cái gì đó như PostSharp để thêm mã cho bạn trong quá trình biên dịch để nó không làm lộn xộn các lớp của bạn với tất cả các thuộc tính đó.
camainc

7

Một số lựa chọn:

  1. Xóa [Serializable]khỏi mô hình

  2. Thêm [DataContract][DataMember]vào mô hình của bạn cùng với [Serializable]

  3. Thêm dòng dưới đây vào App_Start/WebApiConfig.cs

config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();

3

Một giải pháp khác có thể hữu ích trong trường hợp JSON.NET. Có thể đủ để đánh dấu lớp bằng thuộc tính [Newtonsoft.Json.JsonObject].

Tôi đã làm việc với các lớp cs được xây dựng từ xsd và đang thêm một số thuộc tính bằng cách sử dụng các lớp một phần. Sau khi tuần tự hóa json, các thuộc tính này được đánh dấu bằng k_BackingField. Cài đặt JsonFormatter được đề cập trong các câu trả lời khác cũng giúp ích, nhưng đơn giản hơn là đánh dấu một phần lớp bằng thuộc tính [JsonObject].


2

Tôi đang sử dụng DataContractJsonSerializervới một lớp từ một hội đồng khác có Serializablethuộc tính. Đầu ra chứa "k__BackingField". Xóa Serializablethuộc tính (trong hội đồng khác) đã khắc phục điều này. Không chắc chắn lý do tại sao.


0

Giả sử bạn thấy vấn đề này bên trong dự án MVC của mình, tôi thấy rằng việc thay thế việc sử dụng @ Html.JsonData khá đơn giản. Đây là một đoạn mã đã làm việc cho tôi trong quá khứ:

<input type="hidden" id="Model" value="@Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model))" />

Không thanh lịch, nhưng đơn giản trong một nhúm.


0

Tôi đã gặp sự cố này khi tôi có các thuộc tính tự tham chiếu trong lớp của mình chẳng hạn như;

class Person {
 List<Person> Friends { get; set;}
}

Và kết quả là người ấy đã làm bạn với chính mình. Tôi chỉ đảm bảo rằng không có đối tượng tự tham chiếu nào trong tập kết quả của tôi. Hi vọng điêu nay co ich.



0

trong trường hợp của tôi, lỗi này là đối với Phiên bản Newtonsoft.Json, máy chủ tìm kiếm phiên bản 6.0.0 và tôi có phiên bản 11.0, vì vậy tôi phải cài đặt phiên bản 6.0.0


-2

Các bạn, đừng khai báo các thuộc tính như thế này:

public String DiscretionCode { get; set; }
public String DiscretionDescription { get; set; }

Nhưng, hãy tạo ra những cánh hoa khác nhau, như cũ ...

private String discretionCode;

public String DiscretionCode 
{ 
    get { return discretionCode;}
    set { discretionCode = value; }
}

1
Tại sao? Bạn có thể cung cấp cho một reson?
Lucenty,

@Lucenty nó cung cấp một JSON như thế này .. [{"discreationCode": "x"}], khi tuần tự hóa.
Ammar Ameerdeen

Nhưng đây là những gì tôi mong đợi - đây là cách JSON tuần tự hóa dữ liệu. Và tôi nghĩ rằng mã với các cánh khác thường sẽ cho kết quả tương tự.
Lucenty

k_BackingField đã được thêm vào để cho biết một thuộc tính tự động đã được tuần tự hóa. Nếu bạn cấu trúc lại thuộc tính tự động thành thuộc tính và trường sao lưu thì vấn đề sẽ biến mất. Tôi nghĩ rằng có giải pháp tốt hơn trong chủ đề này nhưng điều này hoạt động.
timB33
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.