Изменить имя внутренних объектов для сериализации ASP .NET MVC 4 WebAPI (XML/JSON)

Я создаю веб-службу RESTful с новым Microsoft MVC 4 Класс ApiController и WebAPI. У меня есть класс Person:

public class Person
{
    public string surname { get; set; }
    public string name{ get; set; }
}

и метод HTTP GET по умолчанию работает, возвращая следующее:

<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <surname>John</surname>
    <name>Titor</name>
</Person>

Теперь мне нужен набор аннотаций, который позволит мне изменить имена внутренних объектов по умолчанию, например, я хотел бы изменить surname на msurname. Я попытался добавить следующее:

[XmlElement("msurname")]

аннотацию, но это работает только в том случае, если заголовок Accept моего запроса содержит application/xml (конечно). Я попробовал и использовал аннотацию [DataMember], которая полностью игнорируется.

Есть ли набор аннотаций, который я могу использовать с этим ApiController в WebAPI для сериализации в форматах XML и JSON? Спасибо.

EDIT: исправление, если я использую аннотацию [DataMember] и [DataContract], я получаю желаемое поведение с сериализацией JSON, но не с XML. Противоположное происходит, если я использую [XmlElement].


person frapontillo    schedule 12.03.2012    source источник


Ответы (3)


Поведение, которое вы видите с DataMember, связано с тем, что по умолчанию WebAPI использует XmlSerializer, а не DataContractSerializer. Однако в настоящее время JSON использует JSONDataContractSerializer по умолчанию. Однако в будущем его не будет. Вы можете изменить XML на XmlDataContractSerializer, установив

GlobalConfiguration.Config.Formatters.XmlDataContractSerializer = true;

Таким образом, форматы JSON и XML будут использовать DataContractSerializer.

person Darrel Miller    schedule 12.03.2012
comment
Отлично, спасибо! Я вставил в свой Global.asax.cs Application_Start следующую строку (немного отличающуюся от предложенной вами): GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseDataContractSerializer = true; - person frapontillo; 12.03.2012
comment
Кстати, каким будет поведение по умолчанию в будущем? Будет ли JSON использовать сериализатор с тем же суперклассом, что и XmlSerializer? - person frapontillo; 12.03.2012
comment
@MacGyver Нет. Они хотят заменить сериализатор JSON по умолчанию на JSON.Net. Однако вы всегда можете изменить коллекцию Formatters, чтобы использовать только те, которые вам нужны. - person Darrel Miller; 12.03.2012
comment
Знаем ли мы, сможем ли мы в конечном итоге удалить эту строку с помощью RTM и заставить работать наши атрибуты DataMember/DataContract? - person GONeale; 26.03.2012

Два сериализатора используют разные атрибуты для обработки переименования столбцов и т. д.

Невозможно унифицировать, что вам потребуются оба атрибута.

Однако вы можете использовать другой сериализатор XML/JSON, который распознает другие атрибуты.

ОБНОВЛЕНИЕ
Вы также можете попробовать DataAnnotations и посмотреть, распознают ли их сериализаторы.

person ntziolis    schedule 12.03.2012
comment
[DisplayName("msurname")] на самом деле ничего не меняет, я по-прежнему получаю фамилию в сериализациях XML и JSON. - person frapontillo; 12.03.2012

Это работает так, что вы будете иметь дело с Formatters. Полученные XML-данные создаются XmlMediaTypeFormatter (Класс XmlMediaTypeFomatter).

Я не знаю ни одной встроенной функции, которую вы описываете, но довольно легко написать свой собственный форматтер.

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

Использование JSON.NET с веб-API ASP.NET

person tugberk    schedule 12.03.2012
comment
Да, но я бы предпочел, чтобы это было просто. Я надеялся, что существует какой-то суперкласс аннотаций, который будет учитываться всеми сериализаторами по умолчанию, поскольку система сериализации по умолчанию скрыта. - person frapontillo; 12.03.2012
comment
У @MacGyver у Даррела Миллера есть лучший ответ. - person tugberk; 12.03.2012