◆ 例外フィルター
namespace Sample.Attributes open System; open System.Web; open System.Web.Mvc; open System.Diagnostics type ErrorLogAttribute() = inherit FilterAttribute() // IExceptionFilter インターフェースを実装 interface IExceptionFilter with // アクション・メソッドで例外が発生した場合に実行 member this.OnException(filterContext : ExceptionContext) = if box(filterContext) = null then raise <| new ArgumentNullException("NoContextException") else // 例外が HttpException の場合、ログ出力をせず、 // 指定されたレスポンスコードとエラーメッセージを返す if filterContext.Exception.GetType() = typeof<HttpException> then // 例外を処理済みとみなす filterContext.ExceptionHandled <- true // HTTP Status code を設定 filterContext.HttpContext.Response.StatusCode <- (filterContext.Exception :?> HttpException).GetHttpCode() // エラーView(Shared\CustomError.cshtml)を表示 filterContext.Result <- new ViewResult(ViewName = "CustomError", ViewData = new ViewDataDictionary(filterContext.Exception)) else // エラーログ出力 // 今回はトレースログに出力とする let route = filterContext.RouteData Trace.WriteLine(filterContext.HttpContext.Request.RawUrl) Trace.WriteLine(route.Values.Item("controller").ToString) Trace.WriteLine(route.Values.Item("action").ToString) Trace.WriteLine(filterContext.Exception.StackTrace) Trace.WriteLine(DateTime.Now) // 例外を処理済みとみなす filterContext.ExceptionHandled <- true // HTTP Status code を設定 filterContext.HttpContext.Response.StatusCode <- 500; // エラーView(Shared\CustomError.cshtml)を表示 filterContext.Result <- new ViewResult(ViewName = "CustomError")
◆ Global.fs
namespace Sample.Routing open System open System.Web open System.Web.Mvc open System.Web.Routing open System.Reflection open Sample.Mef open Sample.Controllers open Sample.Attributes type Route = { controller : string action : string id : UrlParameter } type Global() = inherit System.Web.HttpApplication() // フィルターを登録 static member RegisterGlobalFilters(filters:GlobalFilterCollection) = filters.Add(new HandleErrorAttribute()) // ErrorLog フィルターをすべてのコントローラーへ適用する filters.Add(new ErrorLogAttribute()) static member RegisterRoutes(routes:RouteCollection) = routes.IgnoreRoute("{resource}.axd/{*pathInfo}") routes.MapRoute("Default", "{controller}/{action}/{id}", { controller = "Home"; action = "Index" id = UrlParameter.Optional } ) member this.Start() = AreaRegistration.RegisterAllAreas() // フィルターを登録 Global.RegisterGlobalFilters(GlobalFilters.Filters) Global.RegisterRoutes(RouteTable.Routes) |> ignore
◆ Controller
namespace Sample.Controllers open System open System.Web open System.Web.Mvc open Sample.Attributes open System.Diagnostics type ErrorController() = inherit Controller() member this.Index() = // 例外を発生させる(テスト) raise <| new Exception() this.View() :> ActionResult
◆ View(エラー発生時に表示)
// ..\Views\Shared\CustomError.cshtml <!DOCTYPE html> <html> <head> <title>カスタムエラーページ</title> </head> <body> <div> 予期せぬエラーが発生しました。 </div> </body> </html>