首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 服務調用新姿勢:透過元資料動態建立端點

     編輯:關於.NET

典型的 WCF 調用方式有二:一是透過 SvcUtil.exe 或加入 Web 參考產生靜態代理;二是直接使用 ChannelFactory<TChannel> 建立代理。本文示範一種獨特的動態調用方式:利用 WCF 客戶端元資料架構,先以 MetadataExchangeClient 取得服務元資料,再以 WsdlImporter 將其轉換為 ServiceEndpoint,最後據此建立 ChannelFactory 進行調用。此法有助於深入理解 WCF 元資料框架體系。

範例服務定義

沿用熟悉的計算服務:

// 服務契約
[ServiceContract(Namespace = "https://www.artech.com/")]
public interface ICalculator
{
    [OperationContract]
    double Add(double x, double y);
}

// 服務實作
public class CalculatorService : ICalculator
{
    public double Add(double x, double y) { return x + y; }
}

// 組態:發布 MEX 端點
<endpoint address="https://127.0.0.1:3721/calculatorservice" binding="ws2007HttpBinding" contract="Artech.ServiceInvocationViaMetadata.Contracts.ICalculator" />
<endpoint address="https://127.0.0.1:3721/calculatorservice/mex" binding="mexHttpBinding" contract="IMetadataExchange" />

動態調用流程

  1. 建立 MetadataExchangeClient,指定 MEX 繫結。
  2. 呼叫 GetMetadata 取得 MetadataSet。
  3. 建立 WsdlImporter,將已知契約(ICalculator)加入其 KnownContracts。
  4. 呼叫 ImportAllEndpoints 取得 ServiceEndpointCollection。
  5. 依第一個端點建立 ChannelFactory<ICalculator>,創建代理並調用。
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Xml;
using Artech.ServiceInvocationViaMetadata.Contracts;
namespace Artech.ServiceInvocationViaMetadata.Client
{
    class Program
    {
        static void Main(string[] args)
        {
            MetadataExchangeClient metadataExchangeClient = new MetadataExchangeClient(MetadataExchangeBindings.CreateMexHttpBinding());
            MetadataSet metadata = metadataExchangeClient.GetMetadata(new EndpointAddress("https://127.0.0.1:3721/calculatorservice/mex"));
            WsdlImporter wsdlImporter = new WsdlImporter(metadata);
            // 加入已知契約
            ContractDescription contract = ContractDescription.GetContract(typeof(ICalculator));
            wsdlImporter.KnownContracts.Add(new XmlQualifiedName(contract.Name, contract.Namespace), contract);
            ServiceEndpointCollection endpoints = wsdlImporter.ImportAllEndpoints();
            using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(endpoints[0]))
            {
                ICalculator calculator = channelFactory.CreateChannel();
                using (calculator as IDisposable)
                {
                    try
                    {
                        Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, calculator.Add(1, 2));
                    }
                    catch (TimeoutException)
                    {
                        (calculator as ICommunicationObject).Abort();
                        throw;
                    }
                    catch (CommunicationException)
                    {
                        (calculator as ICommunicationObject).Abort();
                        throw;
                    }
                }
            }
            Console.Read();
        }
    }
}

此方式展示了 WCF 元資料架構的靈活性:無需預先產生靜態代理,即可在執行期動態發現並調用服務。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved