6

I have the following method in my WCF service:

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml)]
public int GetOne(string param1, string param2)
{
    return 1;
}

I am sending xml from a Flex application, and it takes an object that looks like this: { param1: "test", param2: "test2" } and turns it into the following request:

POST http://localhost:8012/MyService.svc/GetOne HTTP/1.1
Accept: application/xml
Accept-Language: en-US
x-flash-version: 10,1,53,64
Content-Type: application/xml
Content-Length: 52
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host: localhost:8012
Connection: Keep-Alive
Pragma: no-cache
Cookie: ASP.NET_SessionId=drsynacw0ignepk4ya4pou23

<param1>something</param1><param2>something</param2>

I get the error The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml', 'Json'.. Everything I've read indicates that I just need the content-type to be application/xml, but it still thinks it's Raw for some reason. Given my method signature, I'm confused as to what it's expecting and how I need to form the request so it will accept it as XML.

Am I missing something obvious here? Why does it think it's RAW when it's specifying XML and providing XML?

Edit - Here's the Flex side in case I'm missing something here.

var getOneService:HttpService = new HttpService("myURL");

getOneService.method = "POST";
getOneService.resultFormat = "e4x";
getOneService.contentType = HTTPService.CONTENT_TYPE_XML;
getOneService.headers = { Accept: "application/xml" };

getOneService.send({ param1: "test", param2: "test2" });
Ocelot20
  • 10,510
  • 11
  • 55
  • 96
  • 1
    you set the response format to xml and you are taking input in JSON format as `{ param1: "test", param2: "test2" }` ? is this oK – Waqar Janjua Jul 11 '12 at 19:09
  • I was also going to point out that this '{ param1: "test", param2: "test2" ' was not XML format that you claim to be sending your data in. Providing your Flex code that you use to call the service may help here. – JeffryHouser Jul 11 '12 at 19:18
  • 2
    @WaqarJanjua: That's the Flex object notation. It gets serialized to the XML you see in the request I posted. – Ocelot20 Jul 11 '12 at 19:29
  • ok, 1 question, the method GetOne returns an integer but you set Method="POST" in the webinvoke attribute ? It should not be Get ? – Waqar Janjua Jul 11 '12 at 19:34
  • @www.Flextras.com: Posted the service call, but even when messing with the request in Fiddler I'm unable to get it to recognize it as XML. – Ocelot20 Jul 11 '12 at 19:34
  • Is it possible to change the definition of the REST WCF Service or do you need to get it working with the existing def. – Rajesh Jul 12 '12 at 08:12

2 Answers2

4

I don't think you can pass 2 parameters with a POST operation for the framework to deserialize it automatically. You have try some of the below approaches:

  1. Define your WCF method to be as below:

    [OperationContract]
    [WebInvoke(Method = "POST", 
        BodyStyle = WebMessageBodyStyle.Bare, 
        ResponseFormat = WebMessageFormat.Xml, 
        RequestFormat = WebMessageFormat.Xml, 
        URITemplate="/GetOne/{param1}")]
    public int GetOne(string param1, string param2)
    {
        return 1;
    }
    

    Your raw POST request would looks like as below:

    POST http://localhost/SampleService/RestService/ValidateUser/myparam1 HTTP/1.1
    User-Agent: Fiddler
    Content-Type: application/xml
    Host: localhost
    Content-Length: 86
    
    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">my param2</string>
    
  2. Change your WCF REST method to be as below:

    [OperationContract]
    [WebInvoke(Method = "POST", 
        BodyStyle = WebMessageBodyStyle.WrappedRequest, 
        ResponseFormat = WebMessageFormat.Json, 
        RequestFormat = WebMessageFormat.Json)]
    public int GetOne(string param1, string param2)
    {
        return 1;
    }
    

    Now your raw request should looks something like below:

    POST http://localhost/SampleService/RestService/ValidateUser HTTP/1.1
    User-Agent: Fiddler
    Content-Type: application/json
    Host: localhost
    Content-Length: 86
    
    {"param1":"my param1","param2":"my param 2"}
    
  3. Change your WCF REST method to be as below:

    [OperationContract]
    [WebInvoke(Method="POST", 
        BodyStyle=WebMessageBodyStyle.WrappedRequest, 
        ResponseFormat=WebMessageFormat.Xml, 
        RequestFormat= WebMessageFormat.Xml)]
    public int GetOne(string param1, string param2)
    {
       return 1;
    }
    

    Now your raw request would look like something below:

    POST http://localhost/SampleService/RestService/ValidateUser HTTP/1.1
    User-Agent: Fiddler
    Content-Type: application/xml
    Host: localhost
    Content-Length: 116
    
    <ValidateUser xmlns="http://tempuri.org/"><Username>my param1</Username><Password>myparam2</Password></ValidateUser>
    
Chait
  • 1,052
  • 2
  • 18
  • 30
Rajesh
  • 7,766
  • 5
  • 22
  • 35
  • Your last suggestion ended up being what I went with. I just had to write something on the Flex side to always wrap the parameters with the method name before doing the final request. Thanks! – Ocelot20 Jul 12 '12 at 12:54
1

Valid XML must have a single root element. Also there's no magic in WCF REST that maps XML elements to string parameters. You could take an XElement as your operation parameter.

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Xml)]
public int GetOne(XElement content)
{
    string param1 = content.Elements().First(element => element.Name == "param1").Value;
    string param2 = content.Elements().First(element => element.Name == "param2").Value;

    return 1;
}

The data you send would be something like:

<parameters>
    <param1>something</param1>
    <param2>something</param2>
</parameters>
dcstraw
  • 3,243
  • 3
  • 29
  • 38