2009-09-17 99 views
6

我有这种情况下,我在C#中使用的webservice方法返回一个Business对象,当调用下面的代码的webservice方法时,我得到异常“无法投射对象型的ContactInfo在reference.cs类Web引用类型的ContactInfo”无法投入MyObject类型的对象来键入MyObject

代码:

ContactInfo contactInfo = new ContactInfo(); 
Contact contact = new Contact(); 

contactInfo = contact.Load(this.ContactID.Value); 

任何帮助将非常感激。

+0

您是否最近更新了您的Web引用? – womp 2009-09-17 15:52:21

回答

10

这是因为其中一个ContactInfo对象是Web服务代理,并且位于不同的名称空间中。

这是一个使用asmx风格的web服务的已知问题。在过去,我已经实现了自动浅拷贝来解决它(here's how,但如果我再次这样做,我可能会看看AutoMapper)。

例如,如果您有以下类的组件:

MyProject.ContactInfo 

,你从Web方法返回它的一个实例:

public class DoSomethingService : System.Web.Services.WebService 
{ 
    public MyProject.ContactInfo GetContactInfo(int id) 
    { 
     // Code here... 
    } 
} 

然后,当您添加Web引用到客户端的项目,你实际上得到这样的:

MyClientProject.DoSomethingService.ContactInfo 

这意味着,如果你在客户端AP折叠,调用Web服务来得到一个ContactInfo,你有这样的情况:

namespace MyClientProject 
{ 
    public class MyClientClass 
    { 
     public void AskWebServiceForContactInfo() 
     { 
      using (var service = new DoSomethingService()) 
      { 
       MyClientProject.DoSomethingService.ContactInfo contactInfo = service.GetContactInfo(1); 

       // ERROR: You can't cast this: 
       MyProject.ContactInfo localContactInfo = contactInfo; 
      } 
     } 
    } 
} 

这是对我用我的ShallowCopy类,最后一行:

namespace MyClientProject 
{ 
    public class MyClientClass 
    { 
     public void AskWebServiceForContactInfo() 
     { 
      using (var service = new DoSomethingService()) 
      { 
       MyClientProject.DoSomethingService.ContactInfo contactInfo = service.GetContactInfo(1); 

       // We actually get a new object here, of the correct namespace 
       MyProject.ContactInfo localContactInfo = ShallowCopy.Copy<MyClientProject.DoSomethingService.ContactInfo, MyProject.ContactInfo>(contactInfo); 
      } 
     } 
    } 
} 

注意
这只因为代理类和“真实”类具有完全相同的属性(一个是由Visual Studio生成的)。

0

你如何引用Web服务项目中的类以及消费者项目?如果您只是使用文件链接,这可以很好地解释错误的原因。串行化适用于.NET(Web服务或其他我相信)的方式是使用反射来加载/转储对象的数据。如果这些文件是简单链接的,那么它们实际上会在不同的程序集中被编译为不同的类型,这将解释为什么你有相同的名称但不能在它们之间进行转换。我建议创建一个Web服务和消费者项目引用的'Core'库,并且包含您在任何地方使用的ContactInfo类。

0

这不是问题 - 这是一个功能。

它们是两个独立的类。比较两者,并注意代理类没有构造函数,方法,索引器或原始类的其他行为。这与使用Java程序使用ASMX服务时会发生的情况完全相同。

+1

@Downvoter:想要有人关心你的想法吗?那么你必须说出你的想法。 “-2”并不多说。相反,说出你为什么低估了。 – 2009-09-30 13:16:05

+0

它不应该这样。我们仅在使用生成的代理时出现此问题,而不是在使用CreateChannel方法时,但我们的问题与此帖子相同。我不认为这是一个功能。 – schmoopy 2010-04-08 21:34:40

+0

@schmoopy:他使用的是ASMX Web服务,而不是WCF。没有'CreateChannel'方法。 – 2010-04-09 01:04:33

1

正如其他几个答案所暗示的,这是因为.NET将它们看作两个不同的类。我个人会推荐使用类似AutoMapper的东西。我一直在使用它,它看起来非常棒。你可以用1-2行代码复制你的对象。

Mapper.CreateMap<SourceClass, DestinationClass>(); 
destinationInstance = Mapper.Map<SourceClass, DestinationClass>(sourceInstance); 
0

好像你在两端有两个不同的类。你的应用程序有ContactInfo类,你的web服务也有ContactInfo类。两者是完全不同的两类。一种方法是使用WebService类。如果您在Web服务中使用ContactInfo,那么它将被序列化并在客户端可用以供使用。

1

其实这不是一个错误。这是您自己的项目版本变化的问题! 因为您的最终运行不会在编译时使用原始导入的引用!

例如,我正在制作一个聊天服务器,客户端。我使用了一个数据包结构在客户端项目上传输数据。 然后将相同的引用导入到服务器项目。

当铸造Packet packet = (Packet)binaryFormatter.Deserialize(stream);我得到了同样的错误。因为服务器项目的实际运行参考不是现在在客户端项目中的参考!因为我之后多次重建客户端项目!

在铸造<new object>=(<new object>) <old object>总是新对象需要与旧对象相同的新版本或相同版本!

所以我做的是我建立了一个单独的项目,为Packet类创建一个DLL并将DLL文件导入到两个项目中。

如果我对Packet类做了任何更改,我必须再次将引用导入到客户端和服务器。

那么铸造不会给上述例外!

0

您还可以在添加Web引用时修改由Visual Studio生成的References.cs文件。如果您删除代理生成的类并向您的个人类中添加引用(使用语句),则可以立即使用它们,而不需要浅拷贝/反射或大量映射。 (但是如果重新生成代理层,则必须重新应用修改)。

我也尝试序列化代理对象并将它们反序列化回到我的DTO类中,但这是相当沉重的资源,所以我最终修改了引用cs生成的图层。

希望它能帮助别人来到这里:)

请问。

相关问题