2010-10-01 147 views
1

我有一個自定義WCF服務主機(webServicehost2)和工廠做一些依賴注入(實現自定義IInstanceProvider),也有一些自定義的驗證(impementing定製RequestInterceptor)。自定義錯誤處理消息自定義WebServiceHost

我有一個非常小的問題,當我導航到不存在的REST資源。 例如

http://localhost/restservice.svc/ 
http://localhost/restservice.svc/blah/ 

我得到一個404 Error,OK,預計。

我想知道的是,無論如何,我可以捕獲返回的Http錯誤並將其格式化得更好一些。

回答

3

我不確定是否有更簡單的方法,但我在這裏做了一些快速原型設計,發現實現此目的的一種方法是添加一個定製的IDispatchMessageInspector實現,該實現查看服務的響應消息並替換內容與您自己的自定義HTML頁面。

它去基本上是這樣的:

  • 實現IDispatchMessageInspector.BeforeSendReply()
  • 看回復消息,並抓住httpResponse財產,並檢查它是否是一個基於StatusCode屬性是一個錯誤。
  • 如果發生錯誤,請創建一個全新的WCF消息,並將正文設置爲要提供的HTML內容。
  • 再次將httpResponse和webBodyFormatMessageProperty屬性添加到新消息並將其設置爲答覆。

我有我的例子,這樣做成功,但它的方式醜陋;發佈前我需要清理一下。

+0

嘿,這工作得很好! – Bluephlame 2010-10-04 05:14:41

1

這裏是爲別人attemping這

首先一個的IDispatchMessageInspector

public class CustomResponseFormatterMessageInspector : IDispatchMessageInspector 
    { 
     public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
     { 
      return null; 
     } 

     public void BeforeSendReply(ref Message reply, object correlationState) 
     { 
      var prop = (HttpResponseMessageProperty)reply.Properties[HttpResponseMessageProperty.Name]; 
      if (prop.StatusCode == HttpStatusCode.NotFound) 
      { 
       ErrorResponse(ref reply); 
      } 
     } 

     private void ErrorResponse(ref Message original) 
     { 
      const string ERROR_HTML = @"<html><HEAD><TITLE>Request Error</TITLE></HEAD><BODY> <H1>My Error processing request {1}</H1><P>{0}</P></BODY></html>"; 

      XElement response = XElement.Load(new StringReader(string.Format(ERROR_HTML, "A Resource does not exsist at this location.", HttpStatusCode.NotFound))); 
      Message reply = Message.CreateMessage(original.Version, null, response); 
      reply.Headers.CopyHeadersFrom(original); 
      reply.Properties.CopyProperties(original.Properties); 
      original = reply; 
     } 
    } 

實例的相關代碼snipets然後注入IServiceBehaviour這個我加

ed.DispatchRuntime.MessageInspectors.Add(new CustomResponseFormatterMessageInspector()); 

有可能在這個與我的實現有關的其他代碼,但這是我所添加的。

public class DependencyInjectionServiceBehavior : IServiceBehavior 
    { 
     public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
     { 
      foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers) 
      { 
       var cd = cdb as ChannelDispatcher; 
       if (cd != null) 
       { 
        foreach (EndpointDispatcher ed in cd.Endpoints) 
        { 
         ed.DispatchRuntime.InstanceProvider = 
          new DependencyInjectionInstanceProvider(serviceDescription.ServiceType); 
         ed.DispatchRuntime.MessageInspectors.Add(new CustomResponseFormatterMessageInspector()); 
        } 
       } 
      } 
     } 

     public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) 
     { 
     } 

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