.NET WebAPI Сериализация k_BackingField Nastiness

Когда я сериализую следующее:

[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

Ответ 1

По умолчанию вам не нужно использовать ни [Serializable], ни [DataContract] для работы с веб-API.

Просто оставьте свою модель как есть, и Web 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; }
}

Ответ 2

Существует более общее решение: вы можете настроить Json Serializer на игнорирование атрибута [Serializable], чтобы вам не пришлось изменять атрибуты в ваших классах.

Вы должны внести это изменение конфигурации в начало приложения, то есть в событие Global.asax Application_Start:

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

Вы также можете внести другие изменения в сериализацию Json, например, указать форматы для сериализации дат и многое другое.

Это применимо только к сериализации Web API JSON. Другие сериализации в приложении (сериализация веб-интерфейса API, MVC JsonResult...) не будут затронуты этим параметром.