.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...) не будут затронуты этим параметром.
Ответ 3
Попробуйте использовать DataContract вместо Serializable для маркировки вашего класса. Для более подробной информации о том, почему, посмотрите хорошее сообщение в блоге о сериализации автоматических свойств.