我有几个消息合约,它们使用外部库来标准化多个服务之间的特定功能。他们的代码看起来有点像......
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相同的命名空间中。
答案 0 :(得分:1)
您应该告诉svcutil
重用您的类而不是与代理命名空间作斗争。
这可以使用/reference
参数实现。
将所有这些类移到单独的程序集中也是个好主意。否则,您将在WCF服务器和客户端之间直接引用,这在架构上是不好的。
点击此链接查看示例:
您也可以在Visual Studio中执行相同的任务。请在此处查看我的回答:
How to use a custom type object at the client
<强>更新强>
我做了一些调查。您是对的如果引用包含所有接口和数据协定的程序集,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。
您有两种选择:
使用ChannelFactory
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress(“http://localhost/MathService/Ep1”);
ChannelFactory myChannelFactory = new ChannelFactory(myBinding,myEndpoint);
IMath wcfClient1 = myChannelFactory.CreateChannel();