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

发布于 2024-11-03 17:50:11 字数 2866 浏览 0 评论 0原文

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

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

干杯,

尼克。

Operation '' of contract
'' specifies multiple
request body parameters to be
serialized without any wrapper
elements. At most one body parameter
can be serialized without wrapper
elements. Either remove the extra body
parameters or set the BodyStyle
property on the
WebGetAttribute/WebInvokeAttribute to
Wrapped.

I am trying to expose a C# 4.0 WCF Service with JSON via the following config (set via the WCF Config Editor):

<?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>

When I access /API.svc, I get the previously listed exception message.

If I only specify the following (parameter-less)contract, the service works:

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

If I have methods that require parameters that are non-strings, I get the previously listed exception.

Example:

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

If I change this function like so:

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

It works; but this is only possible for parameters of Type String. How do I respolve this for my other functions like:

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

Tried a lot of google searches, but turned up empty handed, any help is appreciated.

Cheers,

Nick.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

残龙傲雪 2024-11-10 17:50:11

Have you tried setting the WebInvokeAttribute.BodyStyle to Wrapped as the error recommends?

以往的大感动 2024-11-10 17:50:11

问题是您的 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 参数。如果您需要在帖子正文中传递多个值,请创建一个具有所需多个值的轻量级对象,并在帖子正文中接受整个对象。

The problem is that your UriTemplate must specify all the values being passed in except for one. It is fine to have complex types other than strings as parameters, we frequently send lightweight json objects to our services and they come in just fine. Here is an example using your last example.

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

Would work because there is only one parameter being passed in, and it is expected to be in the post body because it is not passed in as a URL parameter, but you can only pass in one body parameter (a parameter passed in the body of the post, not the URL).

You could change your first method like this

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

and it would work, but Password would come in the post body. The best way in this particular example is to do what you did for the second example like so

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

Does that make sense? Basically all values passed in need to be represented as a URL parameter, except for one that can be passed in the post body. If you need multiple values passed in the post body, make a lightweight object that has the multiple values you need and accept that whole object in the post body.

不念旧人 2024-11-10 17:50:11

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

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

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

来源:单击此处

WCF doesn't support more than one parameter with bare body,
if you need pass several parameters in one post method operation,
then we need set the BodyStyle to Wrapped.

So in your case you'd have to change your operation contract to the following:

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

Source: Click Here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文