2009-04-21 74 views
2

我有一個做我的頭在一個奇怪的問題,一個Web服務方法傳遞一個派生類,它接受一個抽象類型

我有一個單一的項目定義以下類:

public abstract class AbstractUnitModel { 

     public void executeRemoteModel(){} 

} 

//this class also implements a seperate interface, but I dont think that is the issue 
public class BlastFurnaceUnitModel : AbstractUnitModel, IUnitModel {} 

現在,如果我嘗試這樣的事情,它按預期工作:

class Class1 
{ 

    public void method1() { 

     BlastFurnaceUnitModel b = new BlastFurnaceUnitModel(); 
     method2(b); 
    } 

    public void method2(AbstractUnitModel a) {} 

} 

現在我有另一個項目,公開Web方法。該方法使用AbstractUnitModel並遠程執行,然後將結果發送回客戶端。因此,在服務器上我有這樣的:

[WebMethod] 
public AbstractUnitModel remotelyExecuteUnitModel(UnitModelWrapperInterface.AbstractUnitModel unitModel) 
     { 

      unitModel.executeRemoteModel(); 
      return unitModel; 

     } 

和客戶端上我有這樣的:

public void remoteExecution() { 

       var unitModelWebService = new UnitModelRemoteServer.RemoteModelExecutionWebService(); 
       unitModelWebService.remotelyExecuteUnitModelCompleted += new UnitModelRemoteServer.remotelyExecuteUnitModelCompletedEventHandler(remoteExecutionCompleted); 
       unitModelWebService.remotelyExecuteUnitModelAsync(this.remoteBF); 
      } 

但我的項目將無法編譯,我得到這些錯誤: 錯誤109的最佳重載對於方法匹配 'CalibrationClient.UnitModelRemoteServer.RemoteModelExecutionWebService.remotelyExecuteUnitModelAsync(CalibrationClient.UnitModelRemoteServer.AbstractUnitModel)' 具有一些無效參數

錯誤110參數「1」:不能轉換從「UnitModelWrapperInterface.BlastFurnaceUnitModel」到「CalibrationClient.UnitModelRemoteServer.AbstractUnitModel」

我想不通爲什麼發生這種情況。我在服務器項目中引用了AbstractUnitModel定義的名稱空間。唯一有點讓我感到有趣的是,它使用的是'CalibrationClient'命名空間中的AbstractUnitModel,而不是UnitModelWrapperInterface。當VS爲客戶端上的webservice生成代理時,它似乎創建了AbstractUnitModel的部分抽象實現。這是我問題的根源嗎?如果是這樣,我該如何解決它?

編輯解決方案:正如所指出的,客戶端需要知道所有可以通過線路發送的類。我最終通過刪除生成的代理類並引用公共庫來解決此問題。這種情況並不理想,但足夠好。

+0

重新評論 - 我錯過了您嘗試在客戶端使用服務器對象的事實。您必須在客戶端使用「舊式」Web服務的代理對象。使用XmlInclude你應該得到BlastFurnaceUnitModel的代理版本。 – 2009-04-21 07:58:53

回答

0

你可以嘗試[XmlInclude]

[XmlInclude(typeof(BlastFurnaceUnitModel))] 
public abstract class AbstractUnitModel {...} 

值得一試,至少...

(編輯),或在方法層面:

[WebMethod(), XmlInclude(typeof(BlastFurnaceUnitModel))] 
public AbstractUnitModel remotelyExecuteUnitModel(...) {...} 

(不太確定有關秒)

+0

感謝Marc的快速響應,但這似乎對我的問題沒有任何影響。我得到相同的編譯錯誤。 – Alex 2009-04-21 07:43:53

1

發生這種情況是因爲WSDL工具創建了代理類(打開服務代碼fi你會看到它們),這些類是用來實例化對象來自服務的類。

如果你想避免這種情況,最好使用WCF。這也涉及多態的返回對象,因爲webservices也無法處理多態(所以remoteExecuteUnitModel方法的返回類型始終爲AbstractUnitModel。

+0

好吧,我想這是因爲客戶端無法確定它已發送的類的性質。在這一點上使用WCF不是一個選項。有沒有一種方法可以讓派生類被包含在代理類中(它不是很優雅,但在這個階段我需要事情的工作)?或者Marc的代碼應該做什麼? – Alex 2009-04-21 07:48:54

0

WebService中公開的類是在服務中的其他名稱空間中創建的參考。

我通常創建像

WebServiceReferenceNS.AbstractUnitModel ToWebServiceModel(AbstractUnitModel unitModel) 
{ 
} 

一個方法來爲WebService準備的類。但我想看看是否有更優雅的解決方案。

相關問題