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.
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.
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=wcfWarning: 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