2009-09-17 103 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生成的圖層。

希望它能幫助別人來到這裏:)

請問。

相關問題