Asp.net-Web-Api
Elmah 不使用帶有 HttpResponseException 的 WebAPI 記錄異常
在我的 WebApi 程式碼中,我引發了一個 HttpResponseException ,它使請求管道短路並生成一個有效的 Http 響應。但是,我正在嘗試將 webApi 與 elmah 日誌記錄集成,但 HttpResponseExeptions 沒有出現。
我為 elmah 設置了 web.config 並具有以下程式碼:
在 Global.asx.cs 中:
static void ConfigureWebApi(HttpConfiguration config) { config.Filters.Add(new ServiceLayerExceptionFilter()); config.Filters.Add(new ElmahHandledErrorLoggerFilter()); config.DependencyResolver = new WebApiDependencyResolver(ObjectFactory.Container); }篩選:
public class ElmahHandledErrorLoggerFilter : ExceptionFilterAttribute { public override void OnException(HttpActionExecutedContext actionExecutedContext) { base.OnException(actionExecutedContext); ErrorSignal.FromCurrentContext().Raise(actionExecutedContext.Exception); } }引發異常的程式碼:
public Task<FileUpModel> UploadFile() { if (Request.Content.IsMimeMultipartContent()) { var provider = new TolMobileFormDataStreamProvider("C:\images\"); var task = Request.Content.ReadAsMultipartAsync(provider).ContinueWith( t => { if (t.IsFaulted || t.IsCanceled) throw new HttpResponseException(HttpStatusCode.InternalServerError); var fileInfo = provider.FileData.FirstOrDefault(); if (fileInfo == null) // the exception here isn't logged by Elmah?! throw new HttpResponseException(HttpStatusCode.InternalServerError); var uploadModel = new FileUpModel { success = true }; return uploadModel; }); return task; } else { throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted")); } }在此之前實施過此操作的任何人都可以讓我知道我做錯了什麼嗎?
Web API 特殊情況 HttpResponseException 在操作中引發並轉換為 HttpResponseMessage,因此您沒有看到您的異常過濾器被呼叫。
在從過濾器中拋出 HttpResponseException 的情況下,情況並非如此。但是,理想情況下,不需要從過濾器中拋出 HttpResponseException,因為您可以通過在提供的輸入上下文上設置 Response 屬性來短路請求。
如上所述,當您引發 HttpResponseException 時,Elmah 過濾器不會擷取和記錄任何內容。更具體地說,如果使用以下語法:
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "It was a bad request"); or throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "HttpResponseException - This request is not properly formatted"));我想在這兩種情況下擷取並記錄錯誤。方法是使用“ActionFilterAttribute”,覆蓋“OnActionExecuted”,並檢查 actionExecutedContext.Response.IsSuccessStatusCode。
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { // when actionExecutedContext.Response is null, the error will be caught and logged by the Elmah filter if ((actionExecutedContext.Response != null) && !actionExecutedContext.Response.IsSuccessStatusCode) { try { var messages = (System.Web.Http.HttpError)((System.Net.Http.ObjectContent<System.Web.Http.HttpError>)actionExecutedContext.Response.Content).Value; StringBuilder stringBuilder = new StringBuilder(); foreach (var keyValuePair in messages) { stringBuilder.AppendLine("Message: Key - " + keyValuePair.Key + ", Value - " + keyValuePair.Value); } Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Web API Failed Status Code returned - " + stringBuilder.ToString())); } catch (Exception ex) { Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Error in OnActionExecuted - " + ex.ToString())); } } }另一方面,我還重寫了“OnActionExecuting”來驗證模型狀態。這使我可以刪除我的操作中的所有檢查。
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) { if (actionContext.ModelState != null && !actionContext.ModelState.IsValid) { StringBuilder stringBuilder = new StringBuilder(); foreach (var obj in actionContext.ModelState.Values) { foreach (var error in obj.Errors) { if(!string.IsNullOrEmpty(error.ErrorMessage)) { stringBuilder.AppendLine("Error: " + error.ErrorMessage); } } } Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Invalid Model State -- " + stringBuilder.ToString())); actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState); } }當然,您需要使用“config.Filters.Add”添加過濾器。