Передача унаследованного объекта в службу WCF с использованием JSON - PullRequest
4 голосов
/ 04 марта 2011

У меня есть два класса, которые я перечислил ниже

public Class Vehicle
{
   int wheels { get ; set}
}

public Class Car:Vehicle
{
   int topspeed { get; set ;}
}

//This is the container class

public Class Message
{
   string ConatinerName { get; set;}
   Vehicle Container;
}

Я определил контракт на обслуживание, который выглядит так, как показано ниже.В этом веб-сервисе включены две конечные точки.Одним из них является SOAP, а другим - Json

//this function gets a message object, looks into the container
public Message GetMessage(Message Input)
{
   Car mycar = (Car)Message.Container;
   mycar.topspeed = 200;
   Message retMessage = new Message();
   retMessage.ContainerName ="Adjusted Car Speed";
   retMessage.Container = mycar;
   return retMessage;
}

Когда я запускаю веб-сервис WCF, собственный тестовый клиент visual studios может вызывать службу с объектом Message и предоставляет возможность проехать на автомобиле илиобъект в контейнере сообщений.Клиент VS использует конечную точку мыла в соответствии с необработанными данными, которые передаются внутрь. Для проверки конечной точки json службы

я использую простой клиент, написанный на Python, который вызывает вышеуказанный метод веб-службы GetMessage(), используяФормат данных JSON.Я передаю объект Car, но когда служба фактически получает

Метод веб-сервиса получает данные, контейнер внутри объекта содержит только объект Vehicle.Я изучил контекст запроса, который получает веб-метод, и он показывает, что получена правильная строка json (как она была отправлена), но .net каким-то образом удаляет свойство класса Car и передает только свойство Vehicle.Таким образом, приведение к автомобилю внутри GetMessage() вызывает исключение, говорящее о том, что вы пытаетесь привести автомобиль к автомобилю, который является недействительным.

Теперь я понимаю, что Container внутри Message имеет типVehicle, но для конечной точки SOAP я могу передать автомобильный объект и объект транспортного средства, но для конечной точки json через контейнер Message можно пропустить только объект Vehicle.

Мой вопрос заключается в том, как я могу заставить среду выполнения .NET распознавать, что я пытаюсь передать Car, а не Vehicle?

Мой код клиента json указан ниже

import urllib2, urllib, json

def get_json(url):
                f = urllib2.urlopen(url)
                resp = f.read()
                f.close()
                return json.loads(resp)

def post(url, data):
                headers = {'Content-Type': 'application/json'}
                request = urllib2.Request(url, data, headers)
                f = urllib2.urlopen(request)
                response = f.read()
                f.close()
                return response

geturl = 'http://localhost:24573/Service1.svc/json/GetMessage'
sendurl = 'http://localhost:24573/Service1.svc/json/SendMessage'

msg = get_json(geturl)
print 'Got', msg
print 'Sending...'
retval = post(sendurl, json.dumps(msg))
print 'POST RESPONSE', retval

Ответы [ 2 ]

4 голосов
/ 05 марта 2011

У меня похожая проблема с использованием Python для вызова WCF с JSON. Примечательно, что для меня это исправило то, что ключ __type был первым в почтовом запросе.

Например, json.dumps(data, sort_keys=True) вернет что-то вроде этого. Службе WCF это не понравилось, потому что __type не был первым в Container. Итак, я бы хотел убедиться, что __type стоит первым. (Кроме того, я очень удивлен, что sort_keys не является рекурсивным.)

Неправильно:

{"Container": {"Model": "El Camino", "TopSpeed": 150, "Wheels": 0, "__type": "Car:#WcfService1"},"WrapperName": "Car Wrapper"}

Справа:

{"Container": {"__type": "Car:#WcfService1", "Model": "El Camino", "TopSpeed": 150, "Wheels": 0},"WrapperName": "Car Wrapper"}

Простой тестовый клиент Python.

import urllib2, urllib, json

def get_json(url):
    f = urllib2.urlopen(url)
    resp = f.read()
    f.close()
    return json.loads(resp)


def post(url, data):
    headers = {'Content-Type': 'application/json'}
    request = urllib2.Request(url, data, headers)
    f = urllib2.urlopen(request)
    response = f.read()
    f.close()
    return response

geturl = 'http://localhost:24573/Service1.svc/json/GetMessage'
sendurl = 'http://localhost:24573/Service1.svc/json/SendMessage'

msg = get_json(geturl)
print 'Got', msg
print 'Sending...'
retval = post(sendurl, json.dumps(msg))
print 'POST RESPONSE', retval
0 голосов
/ 04 марта 2011

Добавить этот атрибут к классу ТС

[KnownType (TypeOf ( "Car"))]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...