0

I am trying to query a WCF web service using Python's request package.

I created a very simple web service in WCF, following the default VS template:

[ServiceContract]
public interface IHWService
{

    [OperationContract]
    [WebInvoke(Method="GET", UriTemplate="SayHello", ResponseFormat=WebMessageFormat.Json)]
    string SayHello();

    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "GetData", ResponseFormat = WebMessageFormat.Json)]
    string GetData(int value);

    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "GetData2", BodyStyle=WebMessageBodyStyle.Bare,  RequestFormat=WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    CompositeType GetDataUsingDataContract(CompositeType composite);

    // TODO: Add your service operations here
}

From Python, I manage to call the first two and get the data back easily.

However, I am trying to call the third one, which adds the concept of complex types.

This is my python code:

import requests as req
import json

wsAddr="http://localhost:58356/HWService.svc"
methodPath="/GetData2"

cType={'BoolValue':"true", 'StringValue':'Hello world'}
headers = {'content-type': 'application/json'}
result=req.post(wsAddr+methodPath,params=json.dumps({'composite':json.dumps(cType)}),headers=headers)

But it does not work, i.e., if I put a breakdown in VS in the GetDataUsingDataContract method, I see that the composite argument is null. I think this comes from a problem in parsing, but I can't quite see what's wrong.

Do you see an obvious mistake there?

Do you know how I can debug inside the parsing mechanism?

EDIT:

Here is the complex type definition:

[DataContract]
public class CompositeType
{
    bool boolValue = true;
    string stringValue = "Hello ";

    [DataMember]
    public bool BoolValue
    {
        get { return boolValue; }
        set { boolValue = value; }
    }

    [DataMember]
    public string StringValue
    {
        get { return stringValue; }
        set { stringValue = value; }
    }
}
SRKX
  • 1,806
  • 1
  • 21
  • 42

1 Answers1

1

You need to send JSON in the POST body, but you are attaching it to the query parameters instead.

Use data instead, and only encode the outer structure:

result=req.post(wsAddr+methodPath,
                data=json.dumps({'composite': cType}),
                headers=headers)

If you encoded cType, you'd send a JSON-encoded string containing another JSON-encoded string, which in turn contains your cType dictionary.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Actually, now the type is not null anymore but both fields are not initialized. I'll add the custom type definition to the question – SRKX Jun 30 '14 at 14:46
  • @SRKX: I have no idea how JSON maps to WCF types though. – Martijn Pieters Jun 30 '14 at 14:54
  • Found it! Just have to make `BodyStyle=WebMessageBodyStyle.WrappedRequest` (not Bare) in the WebInvoke attribute. Thanks a lot. – SRKX Jun 30 '14 at 15:04