WCF - пусть клиент выбирает формат возврата

Я пытаюсь изучить WCF самостоятельно. У меня есть знания C#/ASP.net, но я новичок в WCF. Я использую Visual Studio 2010 для разработки некоторых приложений, пока я учусь.

Я разработал небольшой веб-сервис, который действует как бэкэнд для TODO/диспетчера задач, где пользователь может создавать/удалять/редактировать новые события; все очень просто и элементарно.

Мои вопросы следующие:

  1. Есть ли способ позволить клиенту выбрать желаемый формат возврата (например, xml/json/rdf) без написания новых контрактов на операции?
  2. Как я могу увидеть на клиенте точное сообщение, которое веб-служба отправляет мне (чтобы я мог проверить, является ли это, например, представлением json или сообщением xml).

person Morat    schedule 02.06.2012    source источник


Ответы (4)


Веб-браузеры выбирают форматы ответов с веб-сайтов через согласование содержания и, в частности, через использование Принять и Content-Type HTTP-заголовки.

Например, если вашему клиенту требуется ответ в формате JSON, он отправит серверу HTTP-запрос, который выглядит примерно так:

GET /resource HTTP/1.0
User-Agent: YourClient 1.0
Accept: application/json

Сервер, в свою очередь, ответит таким HTTP-пакетом:

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 20

{ "type" : "json" }

WCF, к сожалению, не оборудован для обработки согласования содержимого «из коробки», но есть действительно хорошая сторонняя библиотека, которая позволяет это без особых усилий, называемая ВкфРестКонтриб. В их документации описаны (довольно простые) шаги, которые необходимо предпринять, чтобы это работает. Подводя итог, вы должны

  1. украсьте свой класс обслуживания в соответствии с типами контента, которые вы хотите поддерживать,
  2. украсить методы, которые вы хотите, чтобы быть в курсе переговоров, и
  3. вернуть сериализуемый бизнес-объект из этого метода.

Что касается вашего второго вопроса, Fiddler — прекрасный выбор для тестирования как клиента, так и сервера.

person ladenedge    schedule 02.06.2012
comment
Сегодня я посмотрю на WcfRestContrib и вернусь к вам. - person Morat; 02.06.2012

При создании службы REST с помощью WCF поддерживается согласование содержимого.

Вам просто нужно установить automaticFormatSelectionEnabled на true на конечной точке.

См. также: Форматирование WCF Web HTTP

person Daniel Hilgarth    schedule 27.09.2012
comment
Я только что нашел указанную выше ссылку на документацию Microsoft после мучительных 2 часов поиска. Этот ответ требует больше любви и внимания, поскольку он превосходит все остальные. - person crush; 22.01.2014

По моему опыту, WCF не очень хорош в этой области. MVC — это большое улучшение с его концепцией «Результаты действий», которая позволяет вам возвращать все, что вы хотите, для данной конечной точки. (И предположительно новый «Web API» будет сочетанием функций WCF и MVC.)

Тем не менее, самый простой способ WCF позволить клиенту выбрать формат ответа — указать тип возвращаемого значения Stream и сериализовать результат в соответствии с требованием.

Итак, объявите метод таким образом и используйте сериализатор(ы) по вашему выбору для JSON и XML.

[OperationBehavior]
[WebGet()]
public Stream SomeOperation(string format)
{
    string test = "Hello world";
    string encodedResult;
    if (format.ToLower() == "xml") {
        // serialize as XML (eg, XML Serializer)
        HttpContext.Current.Response.ContentType = "text/xml";
    }
    else if (format.ToLower() == "json") {
        // serialize as JSON (eg, Newtonsoft Json)
        HttpContext.Current.Response.ContentType = "application/json";
    }
    var ms = new MemoryStream(Encoding.UTF8.GetBytes(encodedResults));
    return ms;
}

Что касается вашего второго вопроса, я бы рекомендовал использовать бесплатный инструмент, такой как Fiddler, для проверки необработанного HTTP-ответа с сервера.

person McGarnagle    schedule 02.06.2012
comment
Спасибо за упоминание Fiddler. Проверит это. Я действительно не понял, что вы имели в виду, указав тип возвращаемой строки и сериализовав результат в соответствии с требованием? Вы имеете в виду, чтобы все мои контракты возвращали строку и выполняли сериализацию самостоятельно, или? - person Morat; 02.06.2012
comment
@ Морат, да, я это и имел в виду. Я обновлю ответ более подробно. - person McGarnagle; 02.06.2012
comment
Спасибо за добавление примера кода; теперь более понятно. Но разве кодирование всего так, как вы предлагаете, не мешает мне использовать все пользовательские типы данных, которые предоставляет прокси? Мне также пришлось бы анализировать ответ от WebService вместо того, чтобы иметь готовые объекты из коробки? - person Morat; 02.06.2012
comment
@ Морат, да, это определенное ограничение этого подхода. Вы не можете сгенерировать этот отличный клиентский прокси-сервер одним щелчком мыши со всей встроенной десериализацией. - person McGarnagle; 02.06.2012

Вместо службы на основе SOAP вы можете попробовать модель REST. Новый способ создания служб REST или HTTP с использованием технологий MS — это использование веб-API, который будет доступен ASP. .NET MVC 4.

Преимущества ОТДЫХА:

  1. Согласование содержимого. Клиент может указать тип данных (JSON, XML..) с помощью параметра Accept-Type в заголовке Request.

  2. Использовать HTTP-методы явно

  3. URI, похожие на структуру каталогов

и больше..

person VJAI    schedule 02.06.2012