WebAPI

Web API #7 Exception Handler

江崑成 2017/10/30 11:28:08
489







前言

在撰寫程式的時候,通常有許多例外狀況需要被處理,在 Web API 中,預設有一個 HandleErrorAttribute,會攔截所有發生的例外,接下來將要說明如何客製一個  ErrorHandleAttribute,在攔截例外後可以進行後續的處理。

Default HandleErrorAttribute

我們先建一個 ErrorController,裡面包含一個 NormalException 的 Action,模擬拋出一個例外,程式碼如下:

public class ErrorController : ApiController
{
   public async Task<IHttpActionResult> NormalException()
   {
       throw new Exception("This is a Exception");

       return Ok();
   }
}

透過模擬我們可以瞭解預設的 HandleError 會幫我們回傳出那些訊息。

  • Message
  • ExceptionMessage
  • ExceptionType
  • StackTrace

Test Web API

Request:

Response:

Custom Exception Filters

Global Exception Filters

新增 GlobalExceptionAttribute.cs,程式碼內容如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Http.Filters;

namespace Hello.WebAPI.ActionFilters
{
    public class GlobalExceptionAttribute : ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext context)
        {
            var response = new HttpResponseMessage(HttpStatusCode.BadRequest)
            {
                Content = new StringContent(context.Exception.Message),
                ReasonPhrase = "Test Exception"
            };

            throw new HttpResponseException(response);
        }
    }
}
 

註冊 Global Exception Filters

修改 WebApiConfig.cs 的程式碼,加入 GlobalExceptionAttribute,程式碼如下:

using Hello.WebAPI.ActionFilters;
using Hello.WebAPI.MessageHandlers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace Hello.WebAPI
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API Filters
            config.Filters.Add(new GlobalExceptionAttribute());

            // Web API Message Handlers
            config.MessageHandlers.Add(new LogMessageHandler());

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
                );

            // 增加 Action 名稱路由規則
            config.Routes.MapHttpRoute(
               name: "DefaultApiWithAction",
               routeTemplate: "api/{controller}/{action}/{id}",
               defaults: new { id = RouteParameter.Optional }
               );
        }
    }
}

Test Web API

Request:

Response:

結論

透過 ExceptionFilterAttribute 的擴充,我們可以針對特定的 Exception 進行處理,也可進行 Log 的記錄,讓系統是可以被追蹤,並且更加可靠。

江崑成