Як видалити k__BackingField з json, коли Deserialize


104

Я отримую k_BackingField у поверненому json після серіалізації файлу xml до об’єкта .net c #.

Я додав атрибут DataContract та DataMember до об’єкта .net c #, але тоді я нічого не отримую на кінці json, client.

[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")]
}

Приклад повернутого json:

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

Відповіді:


45

Синтаксис автоматичного властивості насправді не рекомендується, якщо клас можна використовувати в серіалізації. Причина поля резервного копіювання породжується компілятором, який може бути різним щоразу, коли компілюється код. Це може спричинити проблеми несумісності, навіть якщо клас не зміниться (просто перекомпілюючи код).

Я думаю, що застосування атрибуту DataMember виправить проблему в цьому випадку. Але я рекомендую використовувати повний синтаксис властивостей, якщо клас потрібно використовувати при серіалізації.


Lol, реалізував довгу версію і встановив приватні поля для client.home: Object _fName: "Storefront" _headline: "CEO в StorefrontDoors.NET" _id: "" _industry: ""
Заповнення стека - те, що я РОБІТ

21
додавши, що даний договір у верхній частині класу та дані про кожну властивість, яка мене зацікавила.
Заповнення стека - це те, що я роблю

3
@ AlumCloud.Com +1 для [DataContract] та [DataMember]. Не забудьте додати: System.Runtime.Serialization
Ian Newland

109

Видаліть [Serializable]із свого класу


2
Тепер мені цікаво, чому я вважав, що в першу чергу мені потрібна [Serializable]. Моя серіалізація Xml працює без, а JSON працює без неї.
Rhyous

11
Це не працює зі службами WCF. При поверненні корисного навантаження за допомогою послуг RESTful це не дає жодних даних, якщо ви видалите [Serializable]. Додайте System.Runtime.Serialization та використовуйте [DataContract] для класу, [DataMember] для властивостей.
Ян Ньюленд

Ця відповідь І коментаря Йена, схоже, охоплює обидва випадки. До WCF чи не до WCF, це питання.
granadaCoder

1
@Rhyous - у веб-API вам не потрібна [Serializable], оскільки веб-API налаштований з припущенням, що ви збираєтеся серіалізувати та повертати свої об'єкти (оскільки це в основному вся ідея) - в інших програмах C #, як правило потрібна серіалізація для диференціації об'єктів, що серіалізуються
Історія Йона

Дякую, я затримався [Serializable], тому додавання резервних полів допомогло.
охмусама

59

За замовчуванням серіалізатор WebApi додасть, що синтаксис "__BackingField:" до c # auto-властивостей. Додайте це до свого WebConfig в App_Start, щоб отримати чистіший json, який ви можете шукати.

using Newtonsoft.Json;
...

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

3
Це вирішило проблему. Я думаю, що властивості авто чисті. Використання резервних полів скрізь здається дурним. і вводить багато безладу, а іноді і плутанини.
Ромеш Д. Нірієлла

Це працювало для мене. У моєму випадку у мене був існуючий клас, який вже використовувався веб-сервісами WCF та ASMX, тому я не міг просто змінити його для свого нового проекту WebAPI.
samup

4
Питання в тому, чому на Землі серіалізатор WebApi додасть, що "__BackingField:" за замовчуванням?
Теоман шипахі

хороше рішення. у моєму випадку мені потрібно використовувати [Serializable] збереження у memcache. Потрібна серіалізація.
Bình Nguyễn Quang

2
Що б я зробив без StackOverflow? Дякую.
camainc

35

У нас є деякі об'єкти, які позначені як [Serializable]такі, щоб їх можна було серіалізувати за допомогою традиційних методів, але для використання з веб-API нам потрібно чітко серіалізувати в JSON. Налаштування IgnoreSerializableAttributeне trueдозволить Newtonsoft.Json поводитися як серіалізатори Microsoft, а натомість це просто серіалізуватиме публічні властивості.

TLDR: Додайте це до WebApiConfig.cs:

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

Модератор: Замість того, щоб видаляти дійсно гарну відповідь на запитання, яке було задано кілька разів, видаліть повторне запитання. Це правдива відповідь на правильне запитання.


3
Це має бути правильна відповідь. Видалення серіалізації або використання атрибутів datacontract та datamember не завжди є правильним рішенням.
Хоссам Хамдан

Багато хто з нас, не в тому числі з ОП, не використовують Webapi або MVVM чи що ви, хлопці, про кого. Що таке app_start та webapiconfig, коли у мене звичайний сервіс WCF з милом із service.svc?
Крістіан

10

Простий простий і гідний спосіб викриття даних Нам потрібно виставити дані на об'єкті легко читабельному та послідовному формату


Спочатку видаліть [Serializable]

    [Serializable]

тепер додайте [DataContract] у клас та [DataMember] для властивості, як наведено нижче

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

Сподіваюся, що це допоможе.
Дякую


1
Якщо ви використовуєте веб-API, атрибути DataContract і DataMember взагалі не потрібно додавати атрибути DataContract і DataMember - просто поверніть об'єкт, і він буде автоматично серіалізуватися.
Історія Джона

Якщо хтось починає розробку з нуля, то буде чудово використовувати веб-API, який надаватиме тип повернення об'єкта, не вимагає будь-якого типу кастингу типів для викриття клієнту. Але для питання @ AlumCloud.com, якщо він є в існуючому додатку, тож вирішенням його проблеми буде спочатку видалити [Serializable], потім додати [DataContract] у класі та [DataMember] для властивості, як показано нижче, як було запропоновано
Nagendra Upwanshi

1
Це додає величезної кількості «шуму» вашим заняттям і по суті є непотрібним (дивіться всі інші коментарі). Якщо хтось відчуває необхідність насправді зробити це, я б рекомендував використовувати щось на зразок PostSharp, щоб додати код для вас під час компіляції, щоб він не захаращував ваші класи усіма цими атрибутами.
camainc

7

Пара варіантів:

  1. Зняти [Serializable]з моделі

  2. Додайте [DataContract]і [DataMember]до своєї моделі разом із [Serializable]

  3. Додати рядок до App_Start/WebApiConfig.cs

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

3

Ще одне рішення, яке може допомогти у випадку JSON.NET. Може бути достатньо для позначення класу атрибутом [Newtonsoft.Json.JsonObject].

Я працював з класами cs, побудованими з xsd і додавав деякі властивості за допомогою часткових класів. Після серіалізації json ці властивості були позначені k_BackingField. Налаштування JsonFormatter, згадані в інших відповідях, також допомогли, але простіше було позначити частковий клас атрибутом [JsonObject].


2

Я використовував DataContractJsonSerializerклас з іншої збірки, який мав Serializableатрибут. Вихід містив "k__BackingField". Видалення Serializableатрибута (в іншій збірці) виправило це. Не знаю чому.


0

Припускаючи, що ви бачите цю проблему всередині свого проекту MVC, я виявив, що замінити використання @ Html.JsonData досить просто. Ось фрагмент коду, який працював для мене в минулому:

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

Не такий елегантний, але простий у дрібці.


0

У мене виникло це питання, коли у мене в класі є властивості самовідсилання, такі як;

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

І був результат, людина товаришував із собою. Я просто переконався, що в моєму наборі результатів не було самостійних посилань на об’єкти. Сподіваюся, це допомагає.


0

Мені довелося використовувати атрибути [Serializable], тому видалити його не було можливим.

XmlSerializer ігнорує [XmlAttribute] в WebApi

Вищезгадана резолюція вирішила це для мене.

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;

0

у моєму випадку ця помилка була для версії Newtonsoft.Json, сервер шукав версію 6.0.0, а у мене 11.0, тому мені довелося встановити версію 6.0.0


-2

Друзі, не декларуйте такі властивості:

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

Але, створюйте допоміжні вари, як старі….

private String discretionCode;

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

1
Чому? Не могли б ви дати резонанс?
Луценті

@Lucenty дає такий JSON, як цей .. [{"discreationCode": "x"}], при серіалізації.
Ammar Ameerdeen

Але я би цього очікував - ось як JSON серіалізує дані. І я думаю, що код з допоміжними варами дасть такий же результат.
Луценті

k_BackingField додано, щоб вказати, що автоматеріал було серіалізовано. Якщо ви відновите автоматичну властивість до властивості та резервного поля, проблема усунеться. Я думаю, що в цій темі є кращі рішення, але це працює.
timB33
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.