1

我有几个消息契约,它们使用外部库来标准化多个服务之间的特定功能。他们的代码看起来有点像这样......

using System.ServiceModel;
using Query.Search;

[MessageContract(WrapperName = "MyMessageContract")]
public partial class MyMessageContract
{
    [MessageBodyMember(Name = "Search")]
    public SearchTerms Search { get;  set; }
}

SearchTerms 类位于 Query.Search DLL 中,看起来像这样......

public class SearchTerms : List<SearchTerm> { }

... 与 SearchTerm 类也在同一个 DLL 中。它在服务中工作得很好,并且知道我正在处理 Query.Search 类,但是当我生成代理时,这些类被重新分配到错误的名称空间,并且很难在 UI 中构建服务适配器。我正在使用带有以下参数的 svcutil ...

/t:code /mc /n:*,MyProject.UI.Proxies /ct:System.Collections.Generic.List`1 /l:cs 
/o:WSProxies.cs /config:output.config http://localhost:49207/Service1.svc?wsdl 
http://localhost:49207/Service2.svc?wsdl http://localhost:49207/Service3.svc?wsdl

现在,我知道这里定义的命名空间参数基本上是将我所有的代理命名空间分配给 MyProject.UI.Proxies,如果我删除它,我的 Query.Search 类的命名空间设置正确。但是,这意味着所有其他代理现在都属于定义它们的默认“MyService.DataContracts”命名空间。所以我尝试使用...

/n:MyService.DataContracts,MyProject.UI.Proxies

...但没有运气,因为输出在生成后恢复为“MyService.DataContracts”。我想要做的是让我的代理拥有“MyProject.UI.Proxies”的 UI 命名空间,同时将 SearchTerms 类的命名空间保持为“Query.Search”,而无需手动修改输出文件所以一个新的svcutil 的运行不会消除手动更改。这可能吗?我只是使用 /namespace 参数错误,还是每次生成代理时都必须手动修改输出文件?

编辑:在尝试让这个工作毫无结果的一天之后,我只是创建了一个解决方法,在服务中创建一组类似的类并将它们转换为 Query.Search 类。仍然有兴趣知道我想要的是否可以完成,但形成我收集的内容,在消息合同中使用这些类注定它会被列在与 MC 相同的命名空间下。

4

1 回答 1

1

您应该告诉svcutil重用您的类而不是与代理命名空间抗争。这可以使用/reference参数来实现。

将所有这些类移动到单独的程序集中也是一个好主意。否则,您将在 WCF 服务器和客户端之间直接引用架构上不好的东西。

检查此链接以获取示例:

http://blogs.msdn.com/b/youssefm/archive/2009/10/09/reusing-types-in-referenced-assemblies-with-svcutil-sr-switch.aspx

您也可以在 Visual Studio 中执行相同的任务。在这里查看我的答案:

如何在客户端使用自定义类型对象

更新:

我做了一些调查。没错,如果您引用包含所有接口和数据协定的程序集,则 SVCUtil 不会生成代理类。

该行为与 Visual Studio 不同。Visual Studio 似乎不直接使用 SVCUtil 与 WCF 一起工作。

这是我试过的命令行:

C:\Windows\system32>svcutil /directory:D:\prog\myfolder /r:"D:\prog\SampleWcf\Server\bin\Debug\Contract.dll"  http://localhost:8080/Service/mex 

与您的代码的一个区别是我使用元数据而不是 wsdl。

你有两个选择:

  1. 在 Visual Studio 中生成代理。
  2. 在没有配置文件的情况下使用服务ChannelFactory

    BasicHttpBinding myBinding = new BasicHttpBinding();

    EndpointAddress myEndpoint = new EndpointAddress(" http://localhost/MathService/Ep1 ");

    ChannelFactory myChannelFactory = new ChannelFactory(myBinding, myEndpoint);

    IMath wcfClient1 = myChannelFactory.CreateChannel();

http://msdn.microsoft.com/en-us/library/ms734681.aspx

于 2012-06-09T14:00:44.987 回答