2013-05-15 51 views
0

我已經對服務端自定義錯誤處理程序:WCF:自定義郵件檢查沒有得到有線了

public class MessageInspector : IClientMessageInspector 
    { 
     public void AfterReceiveReply(ref Message reply, object correlationState) 
     { 
      if (reply.IsFault) 
      { 
       //do some processing 
      } 
     } 

     public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel) 
     { 
      return null; 
     } 
} 

public class GlobalErrorHandler : Attribute, IErrorHandler, IServiceBehavior 
    { 
     public void AddBindingParameters(
      ServiceDescription serviceDescription, 
      ServiceHostBase serviceHostBase, 
      Collection<ServiceEndpoint> endpoints, 
      BindingParameterCollection bindingParameters) 
     { 
     } 

     public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
     { 
      IErrorHandler errorHandler = new GlobalErrorHandler(); 

      foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers) 
      { 
       ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher; 

       if (channelDispatcher != null) 
       { 
        channelDispatcher.ErrorHandlers.Add(errorHandler); 

       } 
      } 
     } 

     public bool HandleError(Exception error) 
     { 
      Trace.TraceError(error.ToString()); 

      if (error is FaultException) 
       return false; // Let WCF do normal processing 
      else 
       return true; // Fault message is already generated 
     } 

     public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
     { 
     } 

     public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
     { 
      if (error is FaultException) 
      { 
       // Let WCF do normal processing 
      } 
      else 
      { 
       // Generate fault message manually 
       MessageFault messageFault = MessageFault.CreateFault(
        new FaultCode("Sender"), new FaultReason(error.Message), 
        error, new NetDataContractSerializer()); 
       fault = Message.CreateMessage(version, messageFault, null); 
      } 
     } 

    } 

    public class ErrorHandlerElement : BehaviorExtensionElement 
    { 
     protected override object CreateBehavior() 
     { 
      return new GlobalErrorHandler(); 
     } 

     public override Type BehaviorType 
     { 
      get { return typeof (GlobalErrorHandler); } 
     } 
    } 

我已經在客戶端上定義的自定義消息檢查

我有絲起坐消息檢查的自定義行爲:

public class NewtonsoftJsonBehavior : WebHttpBehavior 
{ 
public override void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime  clientRuntime) 
     { 
      clientRuntime.MessageInspectors.Add(new MessageInspector()); 
     } 
} 

而這種行爲被施加PR ogramatically通過工廠:

public class JsonWebServiceHostFactory : WebServiceHostFactory 
    { 
     protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
     { 
      var host = base.CreateServiceHost(serviceType, baseAddresses); 
      //return host; 
      //ServiceEndpoint ep = host.AddServiceEndpoint(serviceType, new WebHttpBinding(), ""); 
      //host.Description.Endpoints[0].Behaviors.Add(new WebHttpBehavior { HelpEnabled = true });  
      //return host; 

      WebHttpBinding webBinding = new WebHttpBinding(); 

      host.AddServiceEndpoint(serviceType, webBinding, "").Behaviors.Add(new NewtonsoftJsonBehavior()); 
      return host; 
     } 
    } 

然而,當我調試,我產生在服務的FaultException中,globalerrorhandler被調用,但調試從未踏入消息檢查。 任何想法爲什麼?

回答

0

您只使用ApplyClientBehavior將您的消息檢查器放在客戶端。沒有爲服務端的另一種方法:

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
{ 
    if (endpointDispatcher != null) 
    { 
    endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MessageInspector()); 
    } 
} 
+0

如果我如你所說,我得到的消息與行動「」不能在接收器進行處理,由於與EndpointDispatcher中的ContractFilter不匹配。這可能是因爲合同不匹配(發件人和收件人之間的操作不匹配)或發件人和收件人之間的綁定/安全性不匹配。檢查發送方和接收方是否有相同的合同和相同的綁定(包括安全要求,例如消息,傳輸,無)。調用svc時出錯。 – Elena

+0

你將需要做一些基本的調試。您可以從註釋掉消息檢查器中的任何邏輯開始,查看問題是出現在消息檢查器還是消息檢查器邏輯中。 – nvoigt

3

要在WCF服務端創建一個消息檢查,使用替代的IDispatchMessageInspector實現:IClientMessageInspector

一個例子:

服務:

EndpointAddress endpoint = new EndpointAddress("http://localhost:9001/Message"); 

WebServiceHost svcWebHost = new WebServiceHost(typeof(Service.Message), endpoint.Uri); 

CustomServiceBehavior serviceBehavior = new CustomServiceBehavior(); 
svcWebHost.Description.Behaviors.Add(serviceBehavior); 

Binding webHttpBinding = new WebHttpBinding(); 

ServiceEndpoint serviceEndpoint = svcWebHost.AddServiceEndpoint(typeof(Service.IMessage), webHttpBinding, endpoint.Uri); 

ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); 
smb.HttpGetEnabled = true; 
svcWebHost.Description.Behaviors.Add(smb); 

ServiceDebugBehavior sdb = svcWebHost.Description.Behaviors.Find<ServiceDebugBehavior>(); 
sdb.IncludeExceptionDetailInFaults = true; 

svcWebHost.Open(); 

服務合同

[ServiceContract] 
public interface IMessage 
{ 
    [OperationContract] 
    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)] 
    Model.TestResponse Test(); 
} 

服務實現

public class Message : IMessage 
{ 
    public Model.TestResponse Test() 
    { 
     return new Model.TestResponse() { success = true, message = "OK!" }; 
    } 
} 

CustomServiceBehavior實現IServiceBehavior接口:

public class CustomServiceBehavior : IServiceBehavior 
{ 
    public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) 
    { 

    } 

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) 
    { 
     CustomEndpointBehavior endpointBehavior = new CustomEndpointBehavior(); 
     foreach (var endpoint in serviceDescription.Endpoints) 
      endpoint.EndpointBehaviors.Add(endpointBehavior); 
    } 

    public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) 
    { 

    } 
} 

CustomEndpointBehavior實現IEndpointBehavior

public class CustomEndpointBehavior : IEndpointBehavior 
{ 
    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) 
    { 

    } 

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) 
    { 

    } 

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) 
    { 
     var inspector = new CustomDispatchMessageInspector(); 
     endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector); 
    } 

    public void Validate(ServiceEndpoint endpoint) 
    { 

    } 
} 

CustomDispatchMessageInspector實現IDispatchMessageInspector

public class CustomDispatchMessageInspector : IDispatchMessageInspector 
{ 
    public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext) 
    { 
     return null; 
    } 

    public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState) 
    { 
     var httpResponse = ((HttpResponseMessageProperty)reply.Properties["httpResponse"]); 
     httpResponse.Headers.Add("user-agent", "My Browser"); 
    } 
} 

此示例是一個WCF自託管,不包含配置文件(在代碼中配置WCF服務),它返回Json並在HTTP響應(用戶代理:我的瀏覽器)中發送自定義標頭。

爲了測試此代碼:

  1. 創建一個Windows控制檯應用程序
  2. 插入代碼(在一個類中的每個 塊)
  3. 運行的applcation
  4. 使用瀏覽器打開網址: http://localhost:9001/Message/Test
  5. 答案是Json: {「message」:「OK!」,「success」:true}
  6. 您可以檢查響應和 看到自定義標題:「用戶代理:我的瀏覽器」
相關問題