Как опубликовать сложный тип в WCF, используя запросы Python?

#python #wcf #python-2.7 #python-requests

#python #wcf #python-2.7 #python-запросы

Вопрос:

Я пытаюсь запросить веб-службу WCF, используя пакет запросов Python.

Я создал очень простой веб-сервис в WCF, следуя шаблону VS по умолчанию:

 [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
}
  

Из Python мне удается вызвать первые два и легко получить данные обратно.

Тем не менее, я пытаюсь вызвать третий, который добавляет концепцию сложных типов.

Это мой код на python:

 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)
  

Но это не работает, т.Е., Если я помещаю разбивку в VS в GetDataUsingDataContract метод, я вижу, что composite аргумент null . Я думаю, что это связано с проблемой синтаксического анализа, но я не совсем понимаю, что не так.

Вы видите там очевидную ошибку?

Вы знаете, как я могу отлаживать внутри механизма синтаксического анализа?

Редактировать:

Вот определение сложного типа:

 [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; }
    }
}
  

Ответ №1:

Вам нужно отправить JSON в теле сообщения, но вместо этого вы присоединяете его к параметрам запроса.

Используйте data вместо этого и кодируйте только внешнюю структуру:

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

Если вы закодировали cType , вы бы отправили строку в формате JSON, содержащую другую строку в формате JSON, которая, в свою очередь, содержит ваш cType словарь.

Комментарии:

1. На самом деле, теперь тип больше не равен null, но оба поля не инициализированы. Я добавлю определение пользовательского типа к вопросу

2. @SRKX: Я понятия не имею, как JSON сопоставляется с типами WCF.

3. Нашел это! Просто нужно сделать BodyStyle=WebMessageBodyStyle.WrappedRequest (не голый) в атрибуте WebInvoke. Большое спасибо.