我有这种情况,我在C#中使用的Web服务方法返回一个Business对象,当使用以下代码调用webservice方法时,我在参考中得到异常“无法将ContactInfo类型的对象强制转换为类型ContactInfo” .cs类的Web引用
代码:
ContactInfo contactInfo = new ContactInfo();
Contact contact = new Contact();
contactInfo = contact.Load(this.ContactID.Value);
非常感谢任何帮助。
答案 0 :(得分: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
这意味着如果在您的客户端应用程序中调用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生成的。)
答案 1 :(得分:1)
正如其他几个答案所暗示的那样,这是因为.NET将它们视为两个不同的类。我个人会建议使用AutoMapper之类的东西。我一直在使用它,它看起来非常棒。您可以用1-2行代码复制对象。
Mapper.CreateMap<SourceClass, DestinationClass>();
destinationInstance = Mapper.Map<SourceClass, DestinationClass>(sourceInstance);
答案 2 :(得分:1)
实际上这不是错误。这是您自己项目的版本更改的问题! 因为您的最终运行不会在编译时使用原始导入的引用!
例如,我正在制作聊天服务器,客户端。我使用数据包结构在客户端项目上传输数据。 然后将相同的引用导入服务器项目。
当施放Packet packet = (Packet)binaryFormatter.Deserialize(stream);
时,我得到了同样的错误。因为服务器项目的实际运行引用现在不是客户端项目的引用!因为我之后多次重建了客户项目!
在投射<new object>=(<new object>) <old object>
时,新对象总是需要与旧对象更新或相同的版本!
所以我做的是我构建了一个单独的项目来为Packet类创建DLL并将DLL文件导入到两个项目中。
如果我对Packet类做了任何更改,我必须再次将引用导入客户端和服务器。
然后施法不会给出上述异常!
答案 3 :(得分:0)
您如何引用Web服务项目以及消费者项目中的类?如果您只是使用文件链接,这可以很好地解释错误的原因。串行化方式适用于.NET(Web服务或我认为的其他方式)是通过使用反射来加载/转储对象的数据。如果文件只是简单链接,那么它们实际上被编译为不同程序集中的不同类型,这可以解释为什么你有相同的名称但不能在它们之间进行转换。我建议创建一个Web服务和消费者项目引用的“核心”库,并包含您在任何地方使用的ContactInfo
类。
答案 4 :(得分:0)
这不是问题 - 这是一个功能。
他们是两个独立的班级。比较这两者,并注意代理类没有原始类中的构造函数,方法,索引器或其他行为。这与使用Java程序使用ASMX服务时会发生的情况完全相同。
答案 5 :(得分:0)
好像你在两端有两个不同的类。您的应用程序具有ContactInfo类,您的Web服务也具有ContactInfo类。两者都是两个完全不同的类。一种方法是使用WebService类。如果您在Web服务中使用ContactInfo,那么它将被序列化,并将在客户端提供以供使用。
答案 6 :(得分:0)
添加Web引用时,还可以修改Visual Studio生成的References.cs文件。如果删除代理生成的类并向个人类添加引用(使用语句),您将能够立即使用它们,而无需浅层复制/反射或重度映射。 (但是如果重新生成代理层,则必须重新应用修改。)
我还尝试序列化代理对象并在我的DTO类中反序列化它们,但是资源非常繁重,所以我最终修改了引用cs生成层。
希望它会帮助其他人来到这里:)
请