无法将MyObject类型的对象强制转换为MyObject类型

时间:2009-09-17 15:50:06

标签: c# web-services

我有这种情况,我在C#中使用的Web服务方法返回一个Business对象,当使用以下代码调用webservice方法时,我在参考中得到异常“无法将ContactInfo类型的对象强制转换为类型ContactInfo” .cs类的Web引用

代码:

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

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

非常感谢任何帮助。

7 个答案:

答案 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生成层。

希望它会帮助其他人来到这里:)