REST风格的Web服务主体格式

我是WCF新手。 我正在做一些简单的RESTful WCF操作合同。 而且,我有一个关于属性类“WebInvoke”的属性“BodyStyle”的选项的问题。 一个选项是WebMessageBodyStyle.Bare,另一个是WebMessageBodyStyle.Wrapped。 我应该什么时候使用裸? 我应该什么时候使用Wrapped?

感谢您的帮助。

假设你有一些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; } 

根据BodyStyleRequestFormatResponseFormat的组合,您将拥有不同的格式,但通常情况下:

JSONWebMessageBodyStyle.Bare请求和响应将是:

请求:

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

响应:

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

JSONWebMessageBodyStyle.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"}} 

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

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

注意 :您也可以使用return: MessageParameter更改默认的DoWorkResult名称

要回答你的问题,你应该使用哪个WebMessageBodyStyle取决于你的需求,这里没有黄金法则。 对于互操作性,有时可能需要一种或另一种格式。 但请记住裸体风格的一个限制:由于只有一个XML格式的根和一个JSON格式的对象,因此只能将一个parameter passing给方法。 事实上,如果您将服务合同更改为如下所示的内容:

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

一个服务会抛出一个exception:

合约的操作''指定了多个请求主体参数被序列化,没有任何包装元素。 至多有一个身体参数可以被序列化而不包装元素。 要么删除额外的身体参数,要么将WebGetAttribute / WebInvokeAttribute上的BodyStyle属性设置为Wrapped。

包装在操作描述上的用法只是将请求(或响应)包装在一个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); } 

回声操作的input只是一个元素,其中包含文本。 同样,它的响应包含一个操作返回的单个元素。 对于EchoWrapped操作,input实际上是一个元素,其子元素的子元素包含该方法的input。

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