WCF webHttpBinding error with method parameters. "At most one body parameter can be serialized without wrapper elements"

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.

Answers


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


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.


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


Need Your Help

Is it possible to format C++ code with VIM?

vim code-formatting

I am rather new to VIM. I got some source code and this is a mess. At a first sight I would like at least to get a clear and organised view of the code, so I like to get it rightly formatted, I mean

how to parse output of new Date().toString()

java date-format

I need a date format (maybe SimpleDateFormat) that parses reliable the output I get when I call toString() on a Date object. Output on my german(!) system is: "Sun Dec 12 13:45:12 CET 2010", so it ...