.NET WebAPI серіалізація k_BackingField Nastiness


86

Коли я серіалізую наступне:

[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; }
}

Я отримую цей огидний безлад:

<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>

Що дає? Як я можу зробити це гарненьким? Відповіді JSON також містять k_BackingField


Це допомогло мені: stackoverflow.com/questions/15388452 / ...
granadaCoder

Відповіді:


126

За замовчуванням вам не потрібно використовувати ні , [Serializable]ні [DataContract]для роботи з Web API.

Просто залиште свою модель такою, яка є, і веб-API буде серіалізувати всі загальнодоступні властивості для вас.

Тільки якщо ви хочете мати більше контролю над тим, що входить, ви потім прикрасите свій клас [DataContract]та властивості, які потрібно включити [DataMember](оскільки і DCS, і JSON.NET ресепсують ці атрибути).

Якщо з якихось причин вам потрібен [Serializable]ваш клас (тобто ви з якихось причин його серіалізуєте в потік пам'яті, роблячи глибокі копії тощо), тоді вам доведеться використовувати обидва атрибути спільно, щоб запобігти іменам полів резервного копіювання:

[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
Це було все - мені просто потрібно було видалити [Серійний доступ]. Дякую.
Micah

Дякую, Філіпе, з-за кеш-пам’яті потрібно зберігати атрибути .. ДО ВСЬОГО, я завзятий шанувальник вашого блогу .. продовжуйте!
Стівен Паттен,

20
Це просто жахливо. Чому Microsoft коли- небудь не може зробити що-небудь правильно, коли справа стосується серіалізації?
Chris Marisic

Існує більш загальне рішення, як я показую у власній відповіді нижче.
JotaBe

Можливо, проблемою серіалізації є визначення поняття "правильний", дані потрібні кожному по-своєму.
Луїс Феліпе

94

Існує більш загальне рішення: ви можете налаштувати серіалізатор Json на ігнорування [Serializable]атрибута, так що вам не доведеться змінювати атрибути у своїх класах.

Ви повинні змінити цю конфігурацію під час запуску програми, тобто у Application_Startподії Global.asax :

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

Ви також можете внести інші зміни в серіалізацію Json, наприклад, вказати формати для серіалізації дат та багато іншого.

Це стосуватиметься лише серіалізації JSON веб-API. Інші серіалізації в додатку (веб-API XML серіалізація, MVC JsonResult ...) не вплинуть на це налаштування.


4
Мені подобається це рішення набагато краще, ніж додавання атрибутів [DataContract] та [DataMember] скрізь. Дякую!!
Mark Good

1
Не те, чим ви повинні користуватися постійно, але це акуратний фокус. Начебто лом, який допомагає вам обійти безладні ситуації, коли у вас немає розкоші змінювати моделі або глибоко переробляти кодову базу.
uygar.raf

Ви маєте рацію, що це не найкращий спосіб це зробити. Однак у деяких випадках рефакторинг - це не тільки розкіш, але це взагалі неможливо. Наприклад, якщо кодова база використовує WCF або XML-серіалізацію, вона вимагає атрибутів серіалізації контракту даних або XML. Ви не можете цього змінити. На щастя, JSON.NET дуже потужний: він підтримує контракт даних, серіалізацію XML та власні атрибути, і ви можете контролювати, як він використовує їх для серіалізації, або навіть повністю ігнорувати їх. І ви навіть можете додати власну реалізацію. Звичайно, я волію тримати чистоту без атрибутів.
JotaBe

Ось як це має працювати за замовчуванням! Чому ми маємо безглузді дурниці в нашому серіалізованому потоці?
Байрон Уітлок,

1
Якщо ви використовуєте веб-api і орієнтуєтесь на версію 4 .net framework, вам потрібно буде оновити пакет Netwonsoft.Json, щоб це працювало, тобто Update-Package Newtonsoft.Json.
pblack


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