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

WCF 服務發布 WSDL 實戰:HTTP-GET 協定實作細節

     編輯:關於.NET

承接上篇,本文著重於 HTTP-GET 方式發布元資料的內部實作。不同於 WS-MEX 僅需自訂 MEX 端點的 DispatchRuntime,HTTP-GET 需從 ChannelDispatcher 起重建完整分發體系。我們將自訂的 ServiceMetadataBehaviorAttribute 擴充,同時支援兩種發布模式。

核心步驟

  1. 定義 IHttpGetMetadata 契約,其 Get 操作接受/回傳 Message,Action/ReplyAction 為 *。
  2. 讓現有 MetadataProvisionService 實作此介面。
  3. 建立 CreateHttpGetChannelDispatcher 方法,組裝 TextMessageEncodingBindingElement(MessageVersion.None)與 HttpTransportBindingElement(Method=GET)組成 CustomBinding。
  4. 建立 ChannelListener、ChannelDispatcher、EndpointDispatcher,並自訂其 DispatchRuntime:設定 DispatchOperation、MessageOperationFormatter、SyncMethodInvoker、SingletonInstanceContext 等。
  5. 將 ContractFilter、AddressFilter 設為 MatchAllMessageFilter,最後加入 ServiceHost 的 ChannelDispatchers。
private static void CreateHttpGetChannelDispatcher(ServiceHostBase host, Uri listenUri, MetadataSet metadata)
{
    // 建立 Binding
    TextMessageEncodingBindingElement messageEncodingElement = new TextMessageEncodingBindingElement() { MessageVersion = MessageVersion.None };
    HttpTransportBindingElement transportElement = new HttpTransportBindingElement();
    Utility.SetPropertyValue(transportElement, "Method", "GET");
    Binding binding = new CustomBinding(messageEncodingElement, transportElement);

    // 建立 ChannelListener
    IChannelListener listener = binding.BuildChannelListener<IReplyChannel>(listenUri, string.Empty, ListenUriMode.Explicit, new BindingParameterCollection());
    ChannelDispatcher dispatcher = new ChannelDispatcher(listener, "ServiceMetadataBehaviorHttpGetBinding", binding) { MessageVersion = binding.MessageVersion };

    // 建立 EndpointDispatcher
    EndpointDispatcher endpoint = new EndpointDispatcher(new EndpointAddress(listenUri), "IHttpGetMetadata", "https://www.artech.com/");

    // 建立 DispatchOperation,設定 Formatter 與 Invoker
    DispatchOperation operation = new DispatchOperation(endpoint.DispatchRuntime, "Get", "*", "*");
    operation.Formatter = Utility.CreateInstance<IDispatchMessageFormatter>(MessageOperationFormatterType, Type.EmptyTypes, new object[0]);
    MethodInfo method = typeof(IHttpGetMetadata).GetMethod("Get");
    operation.Invoker = Utility.CreateInstance<IOperationInvoker>(SyncMethodInvokerType, new Type[] { typeof(MethodInfo) }, new object[] { method });
    endpoint.DispatchRuntime.Operations.Add(operation);

    // 設定 SingletonInstanceContext 與 InstanceContextProvider
    MetadataProvisionService serviceInstance = new MetadataProvisionService(metadata);
    endpoint.DispatchRuntime.SingletonInstanceContext = new InstanceContext(host, serviceInstance);
    endpoint.DispatchRuntime.InstanceContextProvider = Utility.CreateInstance<IInstanceContextProvider>(SingletonInstanceContextProviderType, new Type[] { typeof(DispatchRuntime) }, new object[] { endpoint.DispatchRuntime });
    dispatcher.Endpoints.Add(endpoint);

    // 設定過濾器
    endpoint.ContractFilter = new MatchAllMessageFilter();
    endpoint.AddressFilter = new MatchAllMessageFilter();

    host.ChannelDispatchers.Add(dispatcher);
}

在 ApplyDispatchBehavior 中依 HttpGetEnabled、HttpGetUrl 決定是否啟用。最終將自訂 Attribute 應用於服務類別,寄宿成功後即可直接用瀏覽器存取 HttpGetUrl 取得 WSDL(圖 2)。

圖 2 通過 IE 獲取發布的元資料

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