XmlFormatter веб-API ASP.NET не работает, возвращается к JsonFormatter

Последние два дня я рвал на себе волосы, пытаясь понять, почему XmlFormatter (через DataContractSerializer) не сериализует данные, которые я возвращаю в своем методе веб-API. WebAPI в любом случае решает использовать JSON, но мне нужно, чтобы результат был в XML (согласно приложению, которое будет использовать этот API). Я настроил свой браузер на отправку Accept: application/xml, чтобы преобразователь использовал XmlFormatter (но результат всегда json).

Контроллер:

public class MyController : ApiController
{
    public MyDataResultList GetData(string someArgument)
    {

        // magic here that gets the data
        MyDataResultList items = MyDataResultList.GetData(someArgument);

        return items;
    }
}

MyDataResultList содержится в dll и имеет такой же макет:

[DataContract]
[CollectionDataContract(Name = "MyDataList")]
[KnownType(typeof(List<MyDataItem>))]
public class MyDataResultList : List<MyDataItem>
{

    [DataMember]
    public string SomethingHere
    {
        get;
        set;
    }

    [DataMember]
    public TimeSpan StartTime
    {
        get;
        set;
    }

    [DataMember]
    public TimeSpan StopTime
    {
        get;
        set;
    }

}

Я попытался установить для UseXmlSerializer значение true, но мне нужно использовать DataContractSerializer на стороне клиента, чтобы правильно десериализовать результаты.

Итак, последний вопрос: можно ли настроить веб-API так, чтобы он выдавал исключение, если он не может сериализоваться с использованием любого средства форматирования? Я считаю (на мой взгляд), что это очень вводит в заблуждение и слишком абстрактно, чтобы он просто молча возвращался к JSON, не давая мне никакого понятия о том, что вызывает это.

Обновление: ручная сериализация MyDataResultList с использованием DCS создает исключение InvalidDataContractException: тип MyDataResultList с атрибутом CollectionDataContractAttribute является недопустимым типом коллекции, поскольку он имеет атрибут DataContractAttribute. Но основной вопрос остается: как заставить веб-API передать это мне вместо того, чтобы молча возвращаться к JSON? (и усложняет отладку)

Update2: сериализатор DataContract, похоже, полностью пропускает свойства SomethingHere/StartTime/EndTime, даже если они содержат [DataMember].


person test-in-prod    schedule 07.04.2014    source источник


Ответы (1)


Ваш способ диагностики правильный, и да, процесс согласования содержимого веб-API попытается найти лучший модуль форматирования на основе набора логики (например, заголовок Accept, если он присутствует, заголовок Content-Type, если Accept-Header отсутствует, спрашивает каждый модуль форматирования, может ли он сериализовать тип и т. д.).

Вы можете отключить это поведение по умолчанию (т. е. найти первое средство форматирования в списке средств форматирования, которые могут записывать/сериализовать тип), выполнив следующие действия. В результате будет сгенерирован ответ 406 Not Acceptable:

DefaultContentNegotiator negotiator = new DefaultContentNegotiator(excludeMatchOnTypeOnly: true);
config.Services.Replace(typeof(IContentNegotiator), negotiator);
person Kiran Challa    schedule 07.04.2014
comment
Достаточно честно, я сделал собственный переговорщик, который просто выдает базовое исключение, если по какой-то причине не может сериализоваться. Спасибо! - person test-in-prod; 08.04.2014