代码之家  ›  专栏  ›  技术社区  ›  Robert W

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

  •  6
  • Robert W  · 技术社区  · 16 年前

    我有一个场景,我在C中使用的WebService方法返回一个业务对象,当用以下代码调用WebService方法时,我在Web引用的reference.cs类中得到异常“无法将contactinfo类型的对象强制转换为contactinfo类型”

    代码:

    ContactInfo contactInfo = new ContactInfo();
    Contact contact = new Contact();
    
    contactInfo = contact.Load(this.ContactID.Value);
    

    任何帮助都将不胜感激。

    7 回复  |  直到 13 年前
        1
  •  10
  •   Community Mohan Dere    9 年前

    这是因为 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服务以获取 接触信息 ,您有这种情况:

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

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

        2
  •  1
  •   John Kraft    16 年前

    正如其他几个答案所建议的,这是因为.NET将它们视为两个不同的类。我个人建议使用 AutoMapper . 我一直在使用它,它看起来非常棒。您可以在1-2行代码中复制对象。

    Mapper.CreateMap<SourceClass, DestinationClass>();
    destinationInstance = Mapper.Map<SourceClass, DestinationClass>(sourceInstance);
    
        3
  •  1
  •   flashk    13 年前

    实际上,这不是一个bug。这是您自己项目的版本更改问题! 因为您的最终运行不会在编译时使用原始导入的引用!

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

    铸造时 Packet packet = (Packet)binaryFormatter.Deserialize(stream); 我也犯了同样的错误。因为服务器项目中实际运行的引用现在不是客户端项目中的引用!因为我已经多次重建客户项目!

    铸造中 <new object>=(<new object>) <old object> 新对象必须是旧对象的新版本或相同版本!

    所以我做的是构建一个单独的项目来为packet类创建一个dll,并将dll文件导入到这两个项目中。

    如果我对包类做了任何更改,我必须再次导入对客户机和服务器的引用。

    那么演员就不会给出上述例外了!

        4
  •  0
  •   Noldorin    16 年前

    如何引用Web服务项目和使用者项目中的类?如果您只是使用了一个文件链接,这可以很好地解释错误的原因。serialiasation对.NET(Web服务或我认为的其他服务)的工作方式是使用反射来加载/转储对象的数据。如果文件只是简单链接的,那么它们实际上是在不同的程序集中编译成不同的类型,这就解释了为什么您具有相同的名称,但不能在它们之间强制转换。我建议创建一个“核心”库,Web服务和消费者项目都引用该库,其中包含 ContactInfo 在任何地方使用的类。

        5
  •  0
  •   John Saunders    16 年前

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

    他们是两个独立的阶级。比较两者,注意代理类没有来自原始类的构造函数、方法、索引器或其他行为。如果你用一个Java程序消耗ASMX服务,这将是完全相同的事情。

        6
  •  0
  •   azamsharp    16 年前

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

        7
  •  0
  •   Francois Verbeeck    15 年前

    还可以在添加Web引用时修改由Visual Studio生成的references.cs文件。如果删除代理生成的类并向您的个人类添加引用(使用语句),则可以直接使用它们,而无需进行浅显的复制/反射或繁重的映射。(但如果重新生成代理层,则必须重新应用修改)。

    我还尝试序列化代理对象,并将其反序列化回我的DTO类中,但从资源的角度来看,这是相当沉重的,所以我最终修改了引用cs生成的层。

    希望它能帮助其他来这里的人:)

    亲切地。