WCF webHttpBinding错误与方法参数。 “至多一个body参数可以在没有包装元素的情况下进行序列化”

时间:2011-04-28 14:35:29

标签: c# wcf json rest

  

合同的操作''   ''指定多个   请求身体参数   序列化没有任何包装   元素。最多一个身体参数   可以在没有包装器的情况下序列化   元素。要么移除额外的身体   参数或设置BodyStyle   物业   WebGetAttribute / WebInvokeAttribute为   缠绕。

我试图通过以下配置(通过WCF配置编辑器设置)使用JSON公开C#4.0 WCF服务:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="iPhoneAPI.API">
        <endpoint address="" behaviorConfiguration="NewBehavior0" binding="webHttpBinding"
          bindingConfiguration="" contract="iPhoneAPI.IApi" />
      </service>
    </services>
    <protocolMapping>
      <add scheme="http" binding="webHttpBinding" bindingConfiguration="" />
    </protocolMapping>
    <behaviors>
      <endpointBehaviors>
        <behavior name="NewBehavior0">
          <webHttp defaultOutgoingResponseFormat="Json" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>  
</configuration>

当我访问/API.svc时,我得到了之前列出的异常消息。

如果我只指定以下(无参数)合同,则服务有效:

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "test")]
GenericApiResult<IEnumerable<LiveFeedEntity>> test();

如果我的方法需要非字符串的参数,我会得到之前列出的异常。

示例:

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "login")]
LoginApiResult Login(String UserName, String Password);

如果我改变这个功能:

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "login/{UserName}/{Password}")]
LoginApiResult Login(String UserName, String Password);

有效;但这只适用于Type String的参数。我如何为我的其他功能解析这个:

[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "logout")]
GenericApiResult<bool> Logout(Guid SessionKey);

尝试了很多谷歌搜索,但空手而归,任何帮助都表示赞赏。

干杯,

尼克。

3 个答案:

答案 0 :(得分:37)

您是否尝试将WebInvokeAttribute.BodyStyle设置为Wrapped,因为错误建议?

答案 1 :(得分:23)

问题是你的UriTemplate必须指定除了一个之外传递的所有值。除了字符串之外还有复杂的类型作为参数,我们经常将轻量级的json对象发送到我们的服务,它们就可以了。以下是使用上一个示例的示例。

[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "logout")]
GenericApiResult<bool> Logout(Guid SessionKey);

可以工作,因为只传入一个参数,并且它应该在post体中,因为它不作为URL参数传入,但是你只能传入一个body参数(传入的参数)帖子的主体,而不是URL)。

您可以像这样更改第一种方法

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "login/{UserName}")]
LoginApiResult Login(String UserName, String Password);

它会起作用,但密码会出现在帖子中。这个特定示例中的最佳方法是执行您为第二个示例所做的操作,如此

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "login/{UserName}/{Password}")]
LoginApiResult Login(String UserName, String Password);

这有意义吗?基本上,传入的所有值都需要表示为URL参数,但可以在帖子正文中传递的值除外。如果您需要在帖子正文中传递多个值,请创建一个具有所需多个值的轻量级对象,并在帖子正文中接受整个对象。

答案 2 :(得分:6)

WCF不支持多个裸体参数, 如果你需要在一个post方法操作中传递几个参数, 然后我们需要将BodyStyle设置为Wrapped

因此,在您的情况下,您必须将操作合同更改为以下内容:

[WebInvoke(Method = "POST", UriTemplate = "evals", BodyStyle = WebMessageBodyStyle.WrappedRequest)]
[OperationContract]
void SubmitVideoPOST(Video videoArg, string userId);

来源:Click Here