我是WCF
的新手。我正在做一些简单的RESTful
WCF
操作合同。而且,我对属性类BodyStyle
的属性WebInvoke
的选项有疑问。一个选项是WebMessageBodyStyle.Bare
,另一个选项是WebMessageBodyStyle.Wrapped
。
Bare
? Wrapped
?感谢您的帮助。
答案 0 :(得分:111)
假设您与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);
服务会引发异常:
合约的'''''''''''''''''''''''''''' 没有任何包装元素的序列化。最多一个身体 参数可以在没有包装元素的情况下序列化。要么删除 额外的body参数或设置BodyStyle属性 WebGetAttribute / WebInvokeAttribute to Wrapped。
答案 1 :(得分:4)
对操作描述包装的使用只是将请求(或响应)包装在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>