簡體   English   中英

如何在MVC ASP.NET中捕獲對(外部)WebApi項目的調用的異常

[英]How to capture exception in MVC ASP.NET to calls to (external) WebApi project

我將外部放在方括號中,但事實並非完全如此。 解釋如下:

我有一個包含以下項目的MVC ASP.NET應用程序(一個解決方案):

  1. 商業邏輯
  2. WebApi(純WebApi2控制器,基於(1)返回json序列化的數據)
  3. 前端(MVC,Razor視圖等)

前端取決於webapi項目,並且前端的RouteConfig為其自身 webapi項目注冊路由:

//register frontend routes, default code
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
//calls webapi project to register its routes:
//var config = GlobalConfiguration.Configuration;
//... call webApi project
config.Routes.MapHttpRoute(
    name: "AppDefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
    name: "AppCustomApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

在此配置中,我可以僅部署和運行前端和訪問功能,如下所示:

現在,我在注冊WebApi項目中發生的異常時遇到了問題。 錯誤和異常處理在FrontEndProject中可以完美地工作:

我可以通過各種方式捕獲這些異常和錯誤(當前我使用HttpModule的自定義實現)

現在,這是一個問題。 異常和錯誤處理不適用於對WebApi項目的調用。 http:// server / application / api / .. )。 在瀏覽器中,我收到正確的答復,例如,嘗試調用不存在的方法將導致:在調試輸出中:

AuditModule: 2016-05-04 14:15:45,201 [56] INFO  AuditModule [(null)] - Request::begin
iisexpress.exe Information: 0 : Request, Method=GET, Url=http://localhost:52258/api/controller_name/fake_method, Message='http://localhost:52258/api/controller_name/fake_method'
iisexpress.exe Information: 0 : Message='controller_name', Operation=DefaultHttpControllerSelector.SelectController
iisexpress.exe Information: 0 : Message='Application.Controllers.controller_nameController', Operation=DefaultHttpControllerActivator.Create
iisexpress.exe Information: 0 : Message='Application.Controllers.controller_nameController', Operation=HttpControllerDescriptor.CreateController
iisexpress.exe Information: 0 : Message='Will use same 'JsonMediaTypeFormatter' formatter', Operation=JsonMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Selected formatter='JsonMediaTypeFormatter', content-type='application/json; charset=utf-8'', Operation=DefaultContentNegotiator.Negotiate
iisexpress.exe Warning: 0 : Message='UserMessage='No HTTP resource was found that matches the request URI 'http://localhost:52258/api/controller_name/fake_method'.', MessageDetail='No action was found on the controller 'controller_name' that matches the request.'', Operation=ApiControllerActionSelector.SelectAction, Status=404 (NotFound), Exception=System.Web.Http.HttpResponseException: Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for deta
   at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)
   at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)
   at System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.<>c__DisplayClass2.<System.Web.Http.Controllers.IHttpActionSelector.SelectAction>b__0()
   at System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter traceWriter, HttpRequestMessage request, String category, TraceLevel level, String operatorName, String operationName, Action`1 beginTrace, Action execute, Action`1 endTrace, Action`1 errorTrace)
iisexpress.exe Warning: 0 : Message='UserMessage='No HTTP resource was found that matches the request URI 'http://localhost:52258/api/controller_name/fake_method'.', MessageDetail='No action was found on the controller 'controller_name' that matches the request.'', Operation=controller_nameController.ExecuteAsync, Status=404 (NotFound), Exception=System.Web.Http.HttpResponseException: Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for deta
   at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)
   at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)
   at System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.<>c__DisplayClass2.<System.Web.Http.Controllers.IHttpActionSelector.SelectAction>b__0()
   at System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter traceWriter, HttpRequestMessage request, String category, TraceLevel level, String operatorName, String operationName, Action`1 beginTrace, Action execute, Action`1 endTrace, Action`1 errorTrace)
   at System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.System.Web.Http.Controllers.IHttpActionSelector.SelectAction(HttpControllerContext controllerContext)
   at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
   at System.Web.Http.Tracing.Tracers.HttpControllerTracer.<ExecuteAsyncCore>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()
iisexpress.exe Information: 0 : Response, Status=404 (NotFound), Method=GET, Url=http://localhost:52258/api/controller_name/fake_method, Message='Content-type='application/json; charset=utf-8', content-length=unknown'
iisexpress.exe Information: 0 : Operation=JsonMediaTypeFormatter.WriteToStreamAsync
iisexpress.exe Information: 0 : Operation=controller_nameController.Dispose
AuditModule: 2016-05-04 14:15:45,236 [56] INFO  AuditModule [(null)] - Request::end
The thread 0x6398 has exited with code 0 (0x0).

並在瀏覽器中(使用正確的http響應代碼,在這種情況下為404):

{
    "Message": "No HTTP resource was found that matches the request URI 'http://localhost:52258/api/controller_name/fake_method'.",
    "MessageDetail": "No action was found on the controller 'controller_name' that matches the request."
}

我試過了:

  1. IHttpModule實現的相同實例無法捕獲; 它捕獲BeginRequest和EndRequest,但不捕獲異常(無論是代碼內還是HTTP)
  2. 每當我使用注冊過濾器的技術時,異常過濾器和處理程序就不會捕獲
  3. 通過config.Services.Replace()替換服務

最初的問題來自於要求對應用程序中發生的一切進行精細的審計跟蹤-前端和API中發生的所有成功和失敗請求。 我正在使用Log4net記錄這些(和其他)事件。

因此,我的問題是-任何人都可以建議另一種方法來在此配置中注冊所有異常(代碼中,http)或指出問題可能來自何處嗎?

謝謝!

upd 1:我可以通過以下標准捕獲代碼(當我在WebApi方法中引發異常時):GlobalConfiguration.Configuration.Filters.Add(new CustomExceptionFilterAttribute());

upd 2:如果我執行以下操作:

public class MyExceptionFilter : IExceptionFilter {...}
GlobalConfiguration.Configuration.Filters.Add(new MyExceptionFilter ());

然后,不會調用MyExceptionFilter。 但是,將調用ExceptionFilterAttribute的impl。

然后剩下的就是如何捕獲http(錯誤的WebApi路徑)和框架(無法解析的參數等等)錯誤和異常。

upd3:已解決。 這是我的解決方案的步驟。 不幸的是,解決方案有點脆弱,需要一定順序的初始化步驟,不太容易出錯:

  1. 在Application_Start中,在注冊任何路由之前:

    GlobalConfiguration.Configuration.Services.Add(typeof(IExceptionLogger),新的AuditExceptionLogger());

  2. 注冊前端路由

  3. 注冊WebApi路線
  4. 注冊404處理程序並創建錯誤控制器

    RouteTable.Routes.MapHttpRoute(name:“ Error404”,routeTemplate:“ {* url}”,默認值:new {controller =“ Error”,action =“ Handle404”}));

  5. 實現DefaultHttpControllerSelector和ApiControllerActionSelector,在那里捕獲異常並替換為

    GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),新的HttpNotFoundAwareDefaultHttpControllerSelector(GlobalConfiguration.Configuration)); GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionSelector),新的HttpNotFoundAwareControllerActionSelector());

而且我還沒有設計CustomError處理-我想對無效的前端請求顯示正確的錯誤頁面

您可以使用外部服務來捕獲異常,例如Exceptionless嗎?

https://exceptionless.com/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM