這是關於如何讓令人煩惱的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