在使用WCF服務時,通常都是用svcutil組建代理程式類和配置,用產生的預設配置就可以調用服務。先來看看產生的預設的配置內容:
View Code
<client>
<endpoint address="http://localhost:8732/ConfigNameService/Service1/"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
contract="IService1" name="WSHttpBinding_IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
其中contract就是代理類中指向介面或契約類,假如contract的定義如下,那麼預設情況下是contract介面的名字
View Code
1 [System.ServiceModel.ServiceContract]
2 public interface IService1
3 {
4 }
但實際上存在多個服務或者需要用命名空間去標記contract時,需要修改用戶端配置中endpoint的中contract的名字,需要其包含命名空間,比如改成如下:
contract="ConfigNameService.IService1"。
按通常的理解,以為系統會按照類型名稱去找代理類中的介面,但實際上並非這樣,僅僅在執行以下代碼時就會提示找不到預設終結點的錯誤。
View Code
1 using (var client = new Service1Client())
2 {
3 Console.WriteLine(client.GetData(1));
4 }
而將contract的值改回"IService1"即可正常調用。
原因是代理類中的contract定義時設定的ConfigurationName決定了配置時需要配置的值,這個屬性很容易被忽視,尤其是通過svcutil產生的代理類,比如以下代碼:
View Code
1 [System.ServiceModel.ServiceContractAttribute(ConfigurationName="IService1")]
2 public interface IService1
3 {
4
5 [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetData", ReplyAction="http://tempuri.org/IService1/GetDataResponse")]
6 string GetData(int value);
7
8 [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/GetDataUsingDataContract", ReplyAction="http://tempuri.org/IService1/GetDataUsingDataContractResponse")]
9 ConfigNameService.CompositeType GetDataUsingDataContract(ConfigNameService.CompositeType composite);
10 }
ConfigurationName就是原服務介面的名字,因此需要手動修改ConfigurationName為需要的值,這裡只能改客戶代理類中的介面定義的ConfigurationName。然後在配置endpoint時的contract的值跟ConfigurationName的值保持一致即可。