2013-05-02 166 views
10

我試圖將自定義的IHttpActionInvoker添加到我的WebAPI應用程序中,以防止在我的操作方法中需要大量重複的異常處理代碼。在WebAPI中使用自定義IHttpActionInvoker進行異常處理

真的似乎沒有太多的關於如何做到這一點,而不是this article。寫我IHttpActionInvoker按照文章之後,我加入這個代碼:

GlobalConfiguration.Configuration.Services.Remove(typeof(IHttpActionInvoker), 
GlobalConfiguration.Configuration.Services.GetActionInvoker()); 

GlobalConfiguration.Configuration.Services.Add(typeof(IHttpActionInvoker), 
new MyApiControllerActionInvoker()); 

進入我的Global.asax文件中的方法。現在,當執行對我的API的調用時,我會在Remove()方法中引發以下異常:

The service type IHttpActionInvoker is not supported 

我想我有兩個問題。

  1. 考慮有沒有看見是一個可怕的很多在那裏有關編寫自定義IHttpActionInvoker類這被認爲是一個很好的方法來解決異常處理的WebAPI的應用程序?

  2. 有誰知道爲什麼我會得到這樣的異常在執行Remove()方法何時以及如何最好地解決這個具體問題?

回答

7

我遇到了與嘗試刪除服務時描述的相同的錯誤。

我發現我不需要從全局配置中刪除任何東西,因爲如果你已經在你的容器中註冊了接口,那麼它將首先解決這個問題。

例如,我使用SimpleInjector,在我的Global.asax我有這樣的:

container.Register<IHttpActionInvoker , MyApiControllerActionInvoker >(); 
// Register the dependency resolver. 
GlobalConfiguration.Configuration.DependencyResolver = 
    new SimpleInjectorWebApiDependencyResolver(container); 

在運行時,需要的時候它是解決MyApiControllerActionInvoker依賴。

然後,您可以在您的客戶ActionInvoker中執行異常處理,並且您的構造函數中設置的任何依賴項都將正確連接。我查看ActionInvoker的原因是爲了獲得構造函數注入,因爲注入屬性似乎需要屬性注入。

而不是刪除/插入,替換似乎工作。 (在Global.asax中)

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionInvoker), new MyApiControllerActionInvoker(fooService)); 
+0

我結束了去過濾器,但這是非常好知道! – Jammer 2013-06-05 14:59:41

1

您是否考慮過註冊異常過濾器?下面是關於一些文檔:

http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling

你不應該倒下的動作調用層,如果你想要做的是在一個特定的方式處理一些例外。

+1

許多開發人員希望捕獲的異常都通過Web API轉換爲「HttpResponseException」。這個異常在調用異常過濾器之前很久就被吞噬了,所以全局異常過濾器不會捕獲所有的東西。 – 2013-08-15 20:16:20

0

至於我可以使用IActionInvoker而不是IHttpActionInvoker。據我所知,IHttpActionInvoker用於異步API調用,不是嗎?

public class RepControllerActionInvoker : ControllerActionInvoker 
{ 
    ILogger _log; 

    public RepControllerActionInvoker() 
     : base() 
    { 
     _log = DependencyResolver.Current.GetService<ILogger>(); 
    } 

    public override bool InvokeAction(ControllerContext controllerContext, string actionName) 
    { 
     try 
     { 
      return base.InvokeAction(controllerContext, actionName); 
     } 
     catch (Exception e) 
     { 
      _log.Error(e); 
      throw new HttpException(500, "Internal error"); 
     } 
    } 
}