2011-03-04 125 views
4

WCF服务我有我已经定义,它看起来像如下所示的服务合同,我下面传递继承的对象使用JSON

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

列出的两个类。这个webservice有两个端点启用。一个是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 Web服务,视觉工作室本地测试客户端能够与Message对象调用服务,并提供在任何汽车或vehcile传递选项对象在Message容器中。该VS客户端使用SOAP端点按该被传递的原始数据。 为了测试服务的JSON端点

我使用Python编写一个简单的客户端使用JSON数据格式,调用上面的web服务GetMessage()方法。我传入一个Car对象,但是当服务实际得到时

webservice方法获取数据,对象内的容器只包含Vehicle对象。 我检查了webmethod接收到的请求上下文,它显示接收到正确的json字符串(因为它已发送),但.net以某种方式剥离Car类属性,并且只传递Vehicle属性。所以在GetMessage()内部的车辆投射出一个异常情况,说你正在试图将车辆投掷到一辆无效的车辆上。

现在我明白了ContainerMessageVehicle型的,但对于SOAP终点,我能够在汽车对象和车辆对象通过,但对于JSON终点只有一个Vehicle对象可以传递通过Message容器。

我的问题是我如何让.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 

回答

4

我有使用Python有类似的问题使用JSON调用WCF。值得注意的是,为我确定的是确保__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

这个属性添加到汽车类

[KnownType(typeof运算( “汽车”))]

+0

我想这和它没有工作 – CrazycodeMonkey 2011-03-04 16:09:17

+0

你的意思[KnownType(typeof运算(车))] 它帮助我,当我面临同样的问题,消耗来自本地客户端的WCF服务 – SKandeel 2012-06-25 16:24:25