类型为“xxx”的对象无法转换为“yyy”类型

问题描述:

我在从服务调用方法时遇到问题。该错误只发生在.NET中,Java似乎正常工作。服务中的大多数方法都可以与.NET一起工作,到目前为止,其中有2个引发了异常。这项服务是开放的,如果你想尝试重现:http://radar.zhaw.ch/services/AirTrafficWebService.wsdl类型为“xxx”的对象无法转换为“yyy”类型

异常

System.ArgumentException occurred 
    Message=Das Objekt mit dem Typ "AirTrafficWcfWrapper.ServiceReference1.Airplane[]" kann nicht in den Typ "AirTrafficWcfWrapper.ServiceReference1.AirplaneTrackingPoint[]" konvertiert werden. 
    Source=mscorlib 
    StackTrace: 
    Server stack trace: 
     bei System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast) 
     bei System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr) 
     bei System.Reflection.RtFieldInfo.InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture, Boolean doVisibilityCheck, Boolean doCheckConsistency) 
     bei System.Reflection.RtFieldInfo.InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture, Boolean doVisibilityCheck) 
     bei System.Reflection.RtFieldInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) 
     bei System.Reflection.FieldInfo.SetValue(Object obj, Object value) 
     bei System.ServiceModel.Dispatcher.OperationFormatter.DeserializeReply(Message message, Object[] parameters) 
     bei System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ProxyRpc& rpc) 
     bei System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc) 
     bei System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) 
     bei System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) 
     bei System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 
    Exception rethrown at [0]: 
     bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 
     bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 
     bei AirTrafficWcfWrapper.ServiceReference1.AirTrafficWebService.getAirplaneTrackingPoints(getAirplaneTrackingPointsRequest request) 
     bei AirTrafficWcfWrapper.ServiceReference1.AirTrafficWebServiceClient.AirTrafficWcfWrapper.ServiceReference1.AirTrafficWebService.getAirplaneTrackingPoints(getAirplaneTrackingPointsRequest request) in D:\Projekte\C#\WP7\Airtraffic\Tests\SilverlightDesktop\AirTrafficWcfWrapper\Service References\ServiceReference1\Reference.cs:Zeile 1234. 
    InnerException: 

它是在一个产生Reference.cs文件抛出这样的:

[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] 
    AirTrafficWcfWrapper.ServiceReference1.getAirplaneTrackingPointsResponse AirTrafficWcfWrapper.ServiceReference1.AirTrafficWebService.getAirplaneTrackingPoints(AirTrafficWcfWrapper.ServiceReference1.getAirplaneTrackingPointsRequest request) { 
     return base.Channel.getAirplaneTrackingPoints(request); //<--HERE 
    } 

.NET电话:

AirplaneTrackingPoint[] tps = _airTrafficService.getAirplaneTrackingPoints(icao, 0, 0, false); 

Java调用:

List<AirplaneTrackingPoint> tps = service.getAirplaneTrackingPoints(icao, 0, 0, false).getItem(); 

编辑:

的响应似乎是由出同时含有飞机对象和AirplaneTrackingPoint制成的单个对象的列表的列表的(例如[0]飞机,[1]纬度,[2]经度,[3]方位等)。所以看起来.NET正在从列表元素中取出第一个元素并将其用作返回值。 Java似乎忽略了列表中列表的第一个元素,而是使列表中的对象脱离列表的其余部分。

有人可以解释这种行为吗?

+0

也许你的服务定义改变了一些东西,忘了更新您的服务参考? –

您是否更改了服务并忘记更新服务参考?也许早些时候,您返回了一个Airplane对象列表,并且您有时候将其更改为返回自己的新数据结构。如果右键单击.NET项目中的服务引用,则可以选择更新它,此时将重新创建为您执行所有操作的代码(在Reference.cs中)。

更新:我可以确认它在VS2010中没有开箱即用。

我试图在.NET 4和.NET 3.5中运行客户端。我第一次从内部的SQL查询字符串中得到一些奇怪的错误异常,现在我只是一遍又一遍地得到了转换错误。我遵循标准的VS2010程序来添加一个服务引用,所以服务有可能被指责,或者WSDL不能与svcutil一起工作(这也是一个可能的问题)。

我得到了以下错误,当我改变了服务引用始终生成消息协定,并使用这些:

{“评出的XML元素从命名空间‘回报’‘’引用不同类型System.String和AirplaneTrackingTest.AirTraffic.Airplane []。使用XML属性为一个或多个元素指定另一个XML名称或命名空间。“}

我会联系服务提供商,并要求正确的测试参数,以他们的方法和他们是否有在C#中的参考客户端实现。

+0

我已经这么做了几次,提供服务的组织已经证实它在大约3年内没有改变。 – SBoss

+0

我已经更新了我的答案,不幸的是我只能确认它没有工作。 – Andreas

+0

感谢您的帮助和努力,我正在努力直接获取XML并解析它。似乎工作到目前为止,但这是一个滋扰。增加了我发现的新信息。 – SBoss

嗨,你需要添加一个演员,假设这两种类型是兼容的。您将从服务中返回AirplaneTrackingPoints并将它们存储为Airplanes,这听起来有点奇怪。

你的Java方法调用getItem不会出现在你的C#代码可能是它吗?

+0

我在调用服务,它是关闭的。我尝试过使用var和使用动态模式。第二件事是设计差异,.NET直接返回您需要在Java中使用getItem()执行的操作 – SBoss

+0

嗯,我不知道java是如何在这里工作的,但是我会说把你的列表改成Airplane类型,应该让它编译,但是你可能需要循环,尽管把它们转换成正确的类型。能够使用适配器模式来使其表现得像你想要的那样,但不知道代码是如何难以做到的 –

+0

如果我尝试接受飞机列表,那么程序将无法编译。我已通过Java验证该服务确实会返回AirplaneTrackingPoint [],而不是Airplane []。 – SBoss