【问题标题】:RESTful web service body formatRESTful Web 服务正文格式
【发布时间】:2013-12-10 22:42:40
【问题描述】:

我是WCF 的新手。我正在做一些简单的RESTfulWCF 操作合同。而且,我对属性类WebInvoke 的属性BodyStyle 的选项有疑问。一个选项是WebMessageBodyStyle.Bare,另一个是WebMessageBodyStyle.Wrapped

  • 什么时候应该使用Bare
  • 什么时候应该使用Wrapped

感谢您的帮助。

【问题讨论】:

    标签: wcf


    【解决方案1】:

    假设您有一些 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> 
    

    注意:您还可以将默认的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 到 Wrapped。

    【讨论】:

    • 非常感谢您的清晰解释,这些解释很有帮助。我投你一票。
    • 非常感谢,解释得很好+1
    • @konrad-kokosa,XML WebMessageBodyStyle.Bare 请求的主标签不应该是实体,而是 DoWork,还是我弄错了?
    • 如果您的接口和 DataContract 周围有一个命名空间包装器怎么办?这会改变 JSON 吗?请参阅我的新问题:stackoverflow.com/questions/39048349/…
    • MSDN 应该复制粘贴这个答案。这比他们自己的要好得多
    【解决方案2】:

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

    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>
    

    来源:http://social.msdn.microsoft.com/Forums/vstudio/en-US/9db6793b-8db9-479b-825c-e781d023f6c1/bodystylewebmessagebodystylewrapped-with-requestformatwebmessageformatxml-for-post?forum=wcf

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-22
      • 1970-01-01
      • 1970-01-01
      • 2012-09-12
      相关资源
      最近更新 更多