Установите формат WebAPI по умолчанию

Мы используем WebAPI, чтобы имитировать обработку устаревшей системы, в результате мы хотели бы, чтобы форматирование ответов по умолчанию для XmlFormatter, а не JsonFormatter. Причина в том, что некоторые из существующих вызовов службы не предоставляют поле Accept: HTTP header.

Я могу добиться этого, удалив JsonFormatter из коллекции Formatters, а затем повторно добавив его, заставив его быть в конце цепочки.

Затем это приведет к отклику формата по умолчанию, используя XmlFormatter. Хотя он работает, он просто не чувствует себя правильно, и хотя я перемещаю Json в конец коллекции, нет никакой гарантии, что XmlFormatter находится в передней части коллекции.

Идеи/мысли?

Спасибо

Ответ 1

Просто добавьте форматировщики в правильном порядке. Если ASP.NET Web API находит два форматирования для одного и того же типа контента, он будет выбирать первый, поэтому очень важно добавить форматировщики в правильном порядке.

//somewhere in Web Api config
config.Formatters.Clear();
config.Formatters.Add(new XmlMediaTypeFormatter());
config.Formatters.Add(new JsonMediaTypeFormatter());

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

Наконец, другой подход - использовать пользовательский IContentNegociator. Это позволит вам выбрать наиболее подходящий MediaTypeFormatter для данного запроса.

//somewhere in Web Api config
config.Services.Replace(typeof(IContentNegotiator), new MyCustomContentNegotiator());

Пример доступен здесь.

Ответ 2

Это возвращается для автоматического сериализации и возврата json, когда тип содержимого json

 var json = config.Formatters.JsonFormatter;
 json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
        config.Formatters.Remove(config.Formatters.XmlFormatter);
((DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;