RESTful web service body format

Jestem nowy w WCF. Wykonuję proste Kontrakty operacyjne WCF. I mam pytanie odnośnie opcji dla właściwości "BodyStyle" klasy atrybutów "WebInvoke". Jedną z opcji jest WebMessageBodyStyle.Bare, a drugi to WebMessageBodyStyle.Zapakowane. Kiedy należy używać Bare? Kiedy należy używać owinięte?

Dziękuję za pomoc.

 44
wcf
Author: Thomas.Benz, 2013-11-26

2 answers

Załóżmy, że masz jakąś umowę z XML request/response i jakąś prostą umowę dotyczącą danych:

[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;
}

W zależności od kombinacji BodyStyle, RequestFormat i ResponseFormat będziesz miał różne formaty, ale ogólnie:

JSON i WebMessageBodyStyle.Bare wniosek i odpowiedź będą:

zapytanie:

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

odpowiedź:

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

JSON i WebMessageBodyStyle.Wrapped Prośba i odpowiedź będą be:

zapytanie:

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

odpowiedź:

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

Uwaga: możesz zmienić domyślną nazwę DoWorkResult na własną:

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

Więc od teraz będzie to:

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

XML oraz WebMessageBodyStyle.Bare wniosek i odpowiedź będą:

zapytanie:

<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>

odpowiedź:

<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 oraz WebMessageBodyStyle.Wrapped Prośba i odpowiedź będą be:

zapytanie:

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

odpowiedź:

 <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> 

Uwaga: Możesz również zmienić domyślną nazwę DoWorkResult za pomocą return: MessageParameter

Aby odpowiedzieć na twoje pytanie, które WebMessageBodyStyle powinieneś użyć zależy od twoich potrzeb i nie ma tu złotej reguły. Dla interoperacyjności czasami może być wymagany jeden lub inny format. Ale pamiętaj o jednym ograniczeniu stylu nagiego ciała: ponieważ w formacie XML jest tylko jeden root i jeden obiekt w formacie JSON do metody można przekazać tylko jeden parametr. W rzeczywistości, jeśli zmieniłeś umowę o świadczenie usług na coś takiego:

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

Usługa rzuciłaby wyjątek:

Operacja "kontraktu" określa wiele parametrów ciała żądania do serializacji bez żadnych elementów owijania. Co najwyżej jedno ciało parametr może być serializowany bez elementów owijania. Usunąć dodatkowych parametrów ciała lub ustawić właściwość BodyStyle na WebGetAttribute / WebInvokeAttribute to Wrapped.

 106
Author: Konrad Kokosa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-26 19:12:01

Użycie owiniętego w opisie operacji po prostu zawija żądanie (lub odpowiedź) w element XML. Na przykład w niniejszej Umowie:

[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);
}

Wejście dla operacji Echo jest po prostu elementem, w którym zawarty jest tekst. Podobnie, jego odpowiedź zawiera pojedynczy element z powrotem operacji. Dla operacji EchoWrapped, wejście jest w rzeczywistości elementem, którego potomek jest elementem, którego potomek zawiera wejście do metody.

Co za obsługa operacji Echo:

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

Czego usługa oczekuje od operacji EchoWrapped:

<EchoWrapped xmlns="http://tempuri.org/"><text>Hello wrapped</text></EchoWrapped>
Źródło: http://social.msdn.microsoft.com/Forums/vstudio/en-US/9db6793b-8db9-479b-825c-e781d023f6c1/bodystylewebmessagebodystylewrapped-with-requestformatwebmessageformatxml-for-post?forum=wcf
 4
Author: Charlie Ou Yang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-26 16:43:46