将派生类传递给采用抽象类型的 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 在客户端上生成 Web 服务的代理时,它会创建 AbstractUnitModel 的部分抽象实现。 这是我的问题的根源吗? 如果是这样,我该如何修复它?
编辑解决方案:正如所指出的,客户端需要了解可以通过网络发送的所有类。 我最终通过删除生成的代理类并引用公共库来解决这个问题。 不理想,但在这种情况下已经足够好了。
I have a bizarre problem that is doing my head in.
I have the following classes defined in a single project:
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 {}
Now if I try something like this, it works as expected:
class Class1
{
public void method1() {
BlastFurnaceUnitModel b = new BlastFurnaceUnitModel();
method2(b);
}
public void method2(AbstractUnitModel a) {}
}
Now I have another project that exposes a web method. This method takes an AbstractUnitModel and executes it remotely, then sends the results back to the client. So on the server I have this:
[WebMethod]
public AbstractUnitModel remotelyExecuteUnitModel(UnitModelWrapperInterface.AbstractUnitModel unitModel)
{
unitModel.executeRemoteModel();
return unitModel;
}
And on the client I have this:
public void remoteExecution() {
var unitModelWebService = new UnitModelRemoteServer.RemoteModelExecutionWebService();
unitModelWebService.remotelyExecuteUnitModelCompleted += new UnitModelRemoteServer.remotelyExecuteUnitModelCompletedEventHandler(remoteExecutionCompleted);
unitModelWebService.remotelyExecuteUnitModelAsync(this.remoteBF);
}
But my project will not compile, and I get these errors:
Error 109 The best overloaded method match for 'CalibrationClient.UnitModelRemoteServer.RemoteModelExecutionWebService.remotelyExecuteUnitModelAsync(CalibrationClient.UnitModelRemoteServer.AbstractUnitModel)' has some invalid arguments
Error 110 Argument '1': cannot convert from 'UnitModelWrapperInterface.BlastFurnaceUnitModel' to 'CalibrationClient.UnitModelRemoteServer.AbstractUnitModel'
I can not figure out why this is happening. I have references in the server project to the namespace where AbstractUnitModel is defined. The only thing that looked a little funny to me is that it is using AbstractUnitModel from the 'CalibrationClient' namespace rather than the UnitModelWrapperInterface. It seems when VS generates the proxy for a webservice on the client it creates a partial abstract implementation of AbstractUnitModel. Is this the source of my problem? If so, how might I go about fixing it?
edit for solution: As pointed out, the client needs to know about all classes that could be sent across the wire. I ended up solving this by removing the generated proxy classes and referencing the common library. Not ideal but good enough in this situation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
发生这种情况是因为 WSDL 工具创建代理类(打开服务代码文件,您将看到它们),这些类是在对象来自服务时用于实例化的类。
如果你想避免这种情况,最好使用WCF。 这也处理多态返回的对象,因为Web服务也无法处理多态(因此remoteExecuteUnitModel方法的返回类型始终是AbstractUnitModel。
This happens because the WSDL tool creates proxy classes (open the service code file and you'll see them) which are the classes used to instantiate when objects come from the service.
If you want to avoid this, it's best to use WCF. This also deals with the polymorphic returned objects, as webservices also can't deal with polymorphism (so the return type of the remotelyExecuteUnitModel method is always AbstractUnitModel.
您可以尝试
[XmlIninclude]
:值得一试,至少...
(编辑)或者在方法级别:(
对第二个不太确定)
You might try
[XmlInclude]
:Worth a try, at least...
(edit) Or at the method level:
(less sure about the second)
WebService 中公开的类是在服务引用内的不同命名空间中创建的。
我通常创建一个方法,例如
为 WebService 准备类。 但我想看看是否有更优雅的解决方案。
The class exposed in your WebService is created in a different namespace inside your service reference.
I usually create a method like
to prepare the classes for the WebService. But I'd like to see if there's a more elegant solution.