方法参数的 WCF webHttpBinding 错误。 “最多可以序列化一个主体参数,而无需包装元素”

问题描述 投票:0回答:3

合约操作'' '' 指定多个 请求体参数为 没有任何包装器的序列化 元素。最多一个身体参数 无需包装器即可序列化 元素。要么删除多余的身体 参数或设置 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);

它有效;但这仅适用于字符串类型的参数。我如何为我的其他功能解决这个问题,例如:

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

尝试了很多谷歌搜索,但空手而归,感谢任何帮助。

干杯,

尼克。

c# wcf json rest
3个回答
45
投票

您是否尝试按照错误建议将 WebInvokeAttribute.BodyStyle 设置为 Wrapped


24
投票

问题是您的 UriTemplate 必须指定除一个之外的所有传入值。使用字符串以外的复杂类型作为参数是很好的,我们经常向我们的服务发送轻量级 json 对象,并且它们传入得很好。这是使用您上一个示例的示例。

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

会起作用,因为只有一个参数被传入,并且它应该在post body中,因为它不是作为URL参数传入的,但是你只能传入一个body参数(在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 参数。如果您需要在帖子正文中传递多个值,请创建一个具有所需多个值的轻量级对象,并在帖子正文中接受整个对象。


8
投票

WCF 不支持裸体多个参数, 如果您需要在一个 post 方法操作中传递多个参数, 然后我们需要将

BodyStyle
设置为
Wrapped

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

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

来源:点击这里

© www.soinside.com 2019 - 2024. All rights reserved.