C# 如何使客户端应用程序将Web服务中的对象识别为它已经知道的类型?

C# 如何使客户端应用程序将Web服务中的对象识别为它已经知道的类型?,c#,web-services,typing,C#,Web Services,Typing,因此,我有一个返回自定义类型的Web服务 public List<MyNS.Product> GetProducts(string filter) { ... } 如何让我的客户端应用程序识别类型为MyServiceReference.Product的返回对象实际上就是它已经知道的MyNS.Product类型?(列表到数组部分不是什么大问题,只是t类型) webservice是作为web站点一部分的常规asmx。我正在执行“添加服务引用”以将服务添加到VisualStudi

因此,我有一个返回自定义类型的Web服务

public List<MyNS.Product> GetProducts(string filter)
{
    ...
}
如何让我的客户端应用程序识别类型为
MyServiceReference.Product
的返回对象实际上就是它已经知道的
MyNS.Product
类型?(列表到数组部分不是什么大问题,只是t类型)

webservice是作为web站点一部分的常规asmx。我正在执行“添加服务引用”以将服务添加到VisualStudio中的客户机项目中

编辑:以下是“添加服务引用”对话框中“高级”按钮的选项。我将集合类型从数组更改为列表。我还试着用产品类型专门选择我的库,但这也没有帮助


如果不修改自动生成的web服务引用代码(我不建议这样做),或者使用包装器类包装您的web引用调用,该类接受并返回具有预期类型的对象,则无法完成此操作


添加web引用时,IDE会根据通过SOAP返回的定义自动生成与web服务接口匹配的类。因此,如果您使用复杂类型的产品,它将自动生成具有相同公共属性的自己的产品类。

添加服务引用时,告诉VS重用业务库中的对象。只要您的服务和客户端使用相同版本的业务库,visual studio就会选择正确的类型,而不是服务代理。

共享类型是WCF中引入的一项功能,而不是旧的asmx web服务。对于旧的ASMX,请尝试SchemaImporterExtension:

编辑: 好啊所以我进行了测试,这可以通过手动创建服务契约、请求和响应类以及手动创建通道来实现。您需要在合同上设置
[XmlSerializerFormat]
,并确保您的对象具有
[SerializableAttribute]
,因为您正在使用soap(.asmx创建一个soap web服务)。客户端应该能够从您的asmx正在创建的soap的wsdl页面中提取键入内容,您只需要确保传递的对象是xml可序列化的

作为一般规则,我将创建一个dto(数据传输对象)来存储传递给客户机的数据,以确保其可序列化,并将其与应用程序的其余部分解耦,以防止更新现有对象引起的问题


这也适用于非.NET客户端,例如,您可以用相同的方式使用java中的.NET的SOAP调用

好吧,我知道这是一篇老文章,但(不幸的是)我也有同样的问题,所以我想我可以分享我的解决方案

开场白

我使用的是asmx web服务(.net 2.0版),我有一个web方法,它返回一个自定义类型(带有[serializable]属性),该类型在项目(实际上是web服务和客户端)共享的程序集中引用

我找到的解决方案是让visual studio为您创建客户机(在客户机项目中),然后修改创建的Reference.cs文件(要查看它,您必须启用“显示所有文件”)

N.B.此外,客户端项目的.NET版本必须为2.0

但要小心

由于它是自动生成的文件,如果更新web服务引用,所有更改都将丢失!所以要多加注意

正如您在这个文件(reference.cs)中所看到的,将使用所有属性重新创建自定义类型,如果类Inrith来自另一个(如我的例子中所示),也将重新创建基类。显然,问题是重新创建的类型与共享程序集的类型不同

我找到的解决方案是重命名生成的类(例如:在名称[YOUR\u BASECLASS\u NAME=>\u YOUR\u BASECLASS\u NAME]之前加一个“\u”),然后在Reference.cs的“using”部分 这样说:

using YOUR_BASECLASS_NAME = SHAREDLIBRARY.BASECLASS
using YOUR_CLASS_NAME = SHAREDLIBRARY.CLASS
对您使用的所有类执行此操作


编译..等等!我知道这不是一个很好的解决方案,但它是我发现的最聪明的解决方案。

如果服务器和客户端都引用同一个程序集,如何获得两种不同的类型?就像我在回答中所写的那样。重用DLL是WCF的功能。使用asmx服务,它无法开箱即用。我刚刚测试过,不完全正确。如果您有可用的业务库,您可以告诉VS重用其中的类型,而不是服务代理。@ValBakhtin这是visual studio更高版本中添加的选项吗?我知道这是WCF的一个选择,但我从来没有使用过web服务,直到我的新工作,他们出于一些可笑的未知原因迫使我们使用VS2005。我知道那是在2008年和2010年。右键单击“服务引用”并选择“配置服务引用”菜单项。当然,刚刚在VS 2010上测试过它,当您添加新的引用时,请单击“高级”按钮。@ValBakhtin但有类似这样的链接(当然是旧的)说该选项存在,但对web服务没有影响。也许这是2010年的新事物。我在高级选项中找到了“重用”复选框,但它总是被选中。我做错了什么吗?当dll版本不匹配且类型具有不同的签名时,或者某个项目引用了库的旧版本时,可能会出现问题。如果dll在两侧完全相同,请在构建解决方案后检查dll版本。问题“发生”是因为它是ASMX web服务。不是WCF。
using YOUR_BASECLASS_NAME = SHAREDLIBRARY.BASECLASS
using YOUR_CLASS_NAME = SHAREDLIBRARY.CLASS