3

所以我有一个返回自定义类型的网络服务

public List<MyNS.Product> GetProducts(string filter)
{
    ...
}

MyNS.Product在另一个程序集中定义。我的客户端应用程序引用了相同的程序集。当我向我的客户端应用程序添加服务引用时,返回类型为MyServiceReference.Product.

var client = new MyServiceReference.dataSoapClient();
var products = client.GetProducts("derp");
// products type is MyServiceReference.Product[]

如何让我的客户端应用程序识别返回的类型对象MyServiceReference.Product实际上是MyNS.Product它已经知道的类型?(数组部分的列表没什么大不了的,只是 T 类型)

Web 服务是作为网站一部分的常规 asmx。我正在执行“添加服务参考”以将服务添加到我在 Visual Studio 中的客户端项目中。

编辑:这是添加服务参考对话框中“高级”按钮的选项。我将集合类型从 Array 更改为 List。我还尝试使用 Product 类型专门选择我的库,但这也无济于事。

添加服务参考选项

4

5 回答 5

3

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

于 2012-05-21T21:20:28.877 回答
2

如果不修改自动生成的 Web 服务参考代码(我不建议这样做),或者使用一个包装类来包装您的 Web 引用调用,该类接收并返回具有预期类型的​​对象,就无法做到这一点。

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

于 2012-05-21T21:18:56.243 回答
0

共享类型是 WCF 中引入的一项功能,但在旧的 asmx Web 服务中没有。对于旧的 ASMX,请尝试 SchemaImporterExtension:链接

编辑:好的。所以我进行了测试,这可以通过手动创建服务合同、请求和响应类以及手动创建通道来完成。你需要[XmlSerializerFormat]在你的合同上设定并确保你的对象有[SerializableAttribute]

于 2012-05-21T21:28:34.560 回答
0

由于您使用的是soap(.asmx 创建一个SOAP Web 服务),因此客户端应该能够从您的asmx 正在创建的soap 的wsdl 页面中提取类型,您只需要确保您传递的对象是xml 可序列化的。

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

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

于 2012-05-21T21:31:01.130 回答
0

好吧,我知道这是一篇旧帖子,但(不幸的是)我有同样的问题,所以我想我可以分享我的解决方案。

序幕

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

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

注意客户端项目的 .NET 版本也必须是 2.0

但请注意!!

作为自动生成的文件,如果您更新 Web 服务引用,所有更改都将丢失!所以要多加注意。

正如您在此文件(reference.cs)中看到的那样,使用所有属性重新创建自定义类型,并且如果类从另一个(如我的情况)inerith,也重新创建基类。明显的问题是重新创建的类型与共享程序集不同。

我找到的解决方案是重命名生成的类(例如:在名称 [YOUR_BASECLASS_NAME => _YOUR_BASECLASS_NAME] 之前放置一个“_”),然后在 Reference.cs 的“使用”部分中放置如下内容:

using YOUR_BASECLASS_NAME = SHAREDLIBRARY.BASECLASS
using YOUR_CLASS_NAME = SHAREDLIBRARY.CLASS

对您使用的所有类执行此操作。

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

于 2015-08-06T10:08:59.157 回答