这是关于如何让令人烦恼的WCF自动生成的客户端工作。容易重现,所有元素都在这里,只需要复制和粘贴,只需要一个命令提示符。WCF,svcutil.exe:如何正确匹配或配置Web服务客户端代码?
在cmd.exe
:
: set up environment
"%VS100COMNTOOLS%"\vsvars32.bat
: create test directory
md wsc
cd wsc
set url=http://xsc-demo.xlogics.eu/DEMO/XTraceWCF/XTrace.svc?wsdl
svcutil /language:cs /config:app.config %url%
notepad app.config
: change client/endpoint/@name to "Gurke" (or whatever)
copy ..\Test.cs .
csc /appconfig:app.config XTrace.cs Test.cs
其中Test.cs
是:
class Test {
static void Main() {
XTraceClient client;
// client = new XTraceClient();
client = new XTraceClient("Gurke"); // match app.config
client.Close();
}
}
给你留下了以下文件:
1.501 app.config
193 Test.cs
31.744 Test.exe
69.284 XTrace.cs
而且(我认为)相关的部分从生成客户代码:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://xlogics.eu/xtrace", ConfigurationName="IXTrace")]
public interface IXTrace
如您所见,它有ConfigurationName="IXTrace"
和public interface IXTrace
。
运行Test.exe
产生以下异常:
System.InvalidOperationException:
Could not find endpoint element with name 'Gurke'
and contract 'IXTrace'in the ServiceModel client
configuration section. This might be because no
configuration file was found for your application,
or because no endpoint element matching this name
could be found in the client element.
然而,我的app.config
似乎匹配(不相关的部分留出了可读性):
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="XTrace" ... >
<readerQuotas ... />
<security mode="None">
<transport ... />
<message ... />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint
address="http://xsc-demo.xlogics.eu/DEMO/XTraceWCF/XTrace.svc"
binding="basicHttpBinding"
bindingConfiguration="XTrace"
contract="IXTrace"
name="Gurke" />
</client>
</system.serviceModel>
</configuration>
正如你所看到的,@contract
是IXTrace
和@name
是Gurke
。那么从哪里来的不匹配呢?
将ConfigurationName="IXTrace"
更改为ConfigurationName="Gurke"
并重新编译不解决问题:同样的错误。
对于这个特殊的问题非常重要。更大的问题是了解这些零碎应该如何一起玩,这样你就可以停止在how-to模式下工作,并将你的头撞到配置问题的墙上(如果Google是任何指标,这种情况并不罕见)。指针欢迎。
更新
在app.config
:
<endpoint name="Heinz" contract="moin.moin.IXTrace" ...
在XTrace.cs
:
namespace moin.moin {
[System.CodeDom.Compiler.GeneratedCodeAttribute(
"System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(
Namespace="http://xlogics.eu/xtrace",
ConfigurationName="moin.moin.IXTrace")]
public interface IXTrace { ...
而且测试程序:
using moin.moin;
class Test {
static void Main() {
XTraceClient client = new XTraceClient("Heinz");
client.Close();
}
}
为什么它不起作用?
更新2
的解决方案是在评论西斯托的答案。它没有工作,因为怪异的配置文件有错误的名称,并没有咨询。事实上,我并不需要编译它,简单的csc Test.cs XTrace.cs
就足够好了。配置文件只需要匹配EXE名称,因此Test.exe
应该是Test.exe.config
。
谢谢,Sixto。你的指导让我做了一些实验。所以至少我已经确定'System.ServiceModel.ServiceContractAttribute'中的'ConfigurationName'和'app.config'中的'endpoint/@ contract'应该匹配。同样,'endpoint/@ name'和构造函数的字符串参数似乎应该匹配。尽管我确实遵循了您的建议,但[其他用户确认](http://stackoverflow.com/q/24993/269126),我还没有成功实现它。这个吓人的垃圾根本行不通。 – Lumi
您的问题实际上是CSC命令中的appconfig开关。从CSC命令中删除该切换并创建一个名为Test.exe.config的app.config文件的副本。另外,WSDL生成的SvcUtil生成的代码不会将IXTrace接口包装在名称空间中,因此contract =“IXTrace”是正确的值。 –
是的,它做到了! 'ren app.config Test.exe.config'所以它一直都是正确的,只是配置文件的名称不匹配。对于后代来说,匹配必须与生成的代码文件中的System.ServiceModel.ServiceContractAttribute(... ConfigurationName =“???”''作为'endpoint/@ contract',它可以是任意的任意字符串,它不会与接口名称没有任何关系,同样,'endpoint/@ name'必须匹配你提供给客户端构造函数的字符串,比如'new XTraceClient(“Heinz”)'。 – Lumi