2009-04-21 59 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准备的类。但我想看看是否有更优雅的解决方案。

相关问题