Подтвердить что ты не робот

Формат тела веб-службы RESTful

Я новичок в WCF. Я делаю несколько простых контрактов на работу с RESTful WCF. И у меня есть вопрос о вариантах для свойства BodyStyle класса атрибутов WebInvoke. Один из вариантов - WebMessageBodyStyle.Bare, а другой - WebMessageBodyStyle.Wrapped.

  • Когда следует использовать Bare?
  • Когда следует использовать Wrapped?

Спасибо за помощь.

4b9b3361

Ответ 1

Предположим, что у вас есть контракт с XML-запросом/ответом и некоторым простым контрактом данных:

[ServiceContract]
public interface IService
{
    ...
    [OperationContract]
    [WebInvoke(Method = "POST",
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Wrapped)]
    Entity DoWork(Entity entity);
    ...
}

[DataContract]
public class Entity
{
    [DataMember]
    public string Name;

    [DataMember]
    public string Value;
}

В зависимости от комбинации BodyStyle, RequestFormat и ResponseFormat у вас будут разные форматы, но в целом:

JSON и WebMessageBodyStyle.Bare запрос и ответ будут следующими:

Запрос:

{"Name":"name","Value":"value"}

Ответ:

{"Name":"ResultName:name","Value":"ResultValue:value"}

JSON и WebMessageBodyStyle.Wrapped запрос и ответ будут следующими:

Запрос:

{"entity":{"Name":"name","Value":"value"}}

Ответ:

{"DoWorkResult":{"Name":"name","Value":"value"}}

Примечание: вы можете изменить имя DoWorkResult по умолчанию:

[return: MessageParameter(Name = "MyResult")]
Entity DoWork(Entity entity);`

так что теперь это будет:

{"MyResult":{"Name":"name","Value":"value"}}

XML и WebMessageBodyStyle.Bare запрос и ответ будут следующими:

Запрос:

<Entity xmlns="http://schemas.datacontract.org/2004/07/WcfService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   <Name>name</Name>
   <Value>value</Value>
</Entity>

Ответ:

<Entity xmlns="http://schemas.datacontract.org/2004/07/WcfService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   <Name>name</Name>
   <Value>value</Value>
</Entity> 

XML и WebMessageBodyStyle.Wrapped запрос и ответ будут следующими:

Запрос:

 <DoWork xmlns="http://tempuri.org/">
   <entity>
      <Name>name</Name>
      <Value>value</Value>
   </entity>
 </DoWork>

Ответ:

 <DoWorkResponse xmlns="http://tempuri.org/">
   <DoWorkResult xmlns:a="http://schemas.datacontract.org/2004/07/WcfService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <a:Name>name</a:Name>
      <a:Value>value</a:Value>
   </DoWorkResult>
 </DoWorkResponse> 

Примечание: вы также можете изменить имя по умолчанию DoWorkResult с помощью return: MessageParameter

Чтобы ответить на ваш вопрос, который WebMessageBodyStyle вы должны использовать, зависит от ваших потребностей, и здесь нет золотого правила. Для обеспечения совместимости иногда может потребоваться тот или иной формат. Но имейте в виду об одном ограничении стиля голого тела: поскольку в формате XML есть только один корень и один объект в формате JSON, только один параметр может быть передан методу. Фактически, если вы изменили контракт на обслуживание на что-то вроде:

[OperationContract]
[WebInvoke(Method = "POST",
    ResponseFormat = WebMessageFormat.Json,
    RequestFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.Bare)]
Entity DoWork(string id, Entity entity);

служба будет генерировать исключение:

Операция '' контракта '' определяет несколько параметров тела запроса для сериализации без каких-либо элементов оболочки. Не более одного тела параметр может быть сериализован без элементов обертки. Либо удалите дополнительные параметры тела или установить свойство BodyStyle на WebGetAttribute/WebInvokeAttribute to Wrapped.

Ответ 2

Использование обернутого в описании операции просто переносит запрос (или ответ) в элемент XML. Например, в этом контракте:

[ServiceContract]
public interface ITest
{
    [OperationContract]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare)]
    string Echo(string text);

    [OperationContract]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped)]
    string EchoWrapped(string text);

    [OperationContract]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped)]
    int Divide(int dividend, int divisor, out int reminder);
}

Вход для операции Echo - это просто элемент, содержащий текст. Аналогично, его ответ содержит один элемент с возвратом операции. Для операции EchoWrapped вход представляет собой элемент, чей дочерний элемент является элементом, дочерний элемент которого содержит вход для метода.

Что ожидает сервис Echo:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">The input</string>

Что ожидает сервис EchoWrapped:

<EchoWrapped xmlns="http://tempuri.org/"><text>Hello wrapped</text></EchoWrapped>

Источник: http://social.msdn.microsoft.com/Forums/vstudio/en-US/9db6793b-8db9-479b-825c-e781d023f6c1/bodystylewebmessagebodystylewrapped-with-requestformatwebmessageformatxml-for-post?forum=wcf