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; }
根据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>
注意 :您也可以使用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