ASP.NET MVC 3 アプリケーションに取り組んでいます。アプリのいわゆる「ビジネス層」では、状況に応じて特定の種類の例外を常にスローすることを決定しました。ユーザーが許可されていないことをしようとした場合の例外タイプの階層と、アプリケーションが特定のアイテムを (ID または名前などで) 見つけられない場合の特別な例外があります。
これは、C# コードでは次のようになります。
// ... more stuff
public Something GetSomething(int id, User currentUser){
var theSomething = SomethingRepository.Get(id);
if(theSomething == null){
throw new SomethingNotFoundException(id, "more details");
}
if(!PermissionService.CanLoadSomething(currentUser)){
throw new NotAuthorizedException("You shall not pass");
}
// the rest of the method etc etc
// ...
}
...SomethingNotFoundException
とNotAuthorizedException
は customException
です。
この種の例外と Http ステータス コード (404 Not Found / 403 Forbidden) の間に何らかの直接マッピングがあり、それに応じて Controller メソッドでこれらのエラーを処理する必要があります (404/403 CustomError ページなどを表示します)。 . 今、私たちが望むのは、コントローラーのアクションでこれを行う必要がないようにすることです:
public ViewResult Get(int id){
try{
var theSomething = MyService.GetSomething(id, theUser);
}
catch(SomethingNotFoundException ex){
throw new HttpException(404, ex);
}
catch(NotAuthorizedExceptionex){
throw new HttpException(403, ex);
}
}
カスタムのHandleErrorAttributeまたはカスタムのActionFilterAttributeを使用してGlobal.asaxに登録する方法が必要だと確信していますが、それを機能させる方法がわかりません。
試行 1 : HandleErrorAttribute
最初に、HandleErrorAttribute のサブクラスを作成して、OnException
メソッドをオーバーライドしようとしました。
public override void OnException(ExceptionContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
Exception exception = filterContext.Exception;
// Map some of the Business Exception to correspounding HttpExceptions !
if (exception is ObjectNotFoundException)
{
// consider it as a NotFoundException !
exception = new HttpException((int)HttpStatusCode.NotFound, "Not found", exception);
filterContext.Exception = exception;
}
else if (exception is NotAuthorizedException)
{
// consider it as a ForbiddenException
exception = new HttpException((int)HttpStatusCode.Forbidden, "Forbidden", exception);
filterContext.Exception = exception;
}
base.OnException(filterContext);
}
GlobalFilterCollection
...それをGlobal.asaxに追加します ...しかし、404/403 カスタム エラー ページを表示する代わりに、通常の 500 エラーのように処理されます...
試行 2: ActionFilterAttribute
ActionFilterAttribute
また、それを にして、次のようにメソッドをオーバーライドしようとしましたOnActionExecuted
:
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
Exception exception = filterContext.Exception;
if(exception!=null)
{
// Map some of the Business Exception to correspounding HttpExceptions !
if (exception is ObjectNotFoundException)
{
// consider it as a NotFoundException !
var wrappingException = new HttpException((int)HttpStatusCode.NotFound, "Not found", exception);
exception = wrappingException;
filterContext.Exception = exception;
}
else if (exception is NotAuthorizedException)
{
// consider it as a ForbiddenException
var wrappingException = new HttpException((int)HttpStatusCode.Forbidden, "Forbidden", exception);
exception = wrappingException;
filterContext.Exception = exception;
}
}
base.OnActionExecuted(filterContext);
}
...それでも、404 または 403 の代わりに 500 エラー ページが表示されます ...
私は何か間違っていますか?おそらくより良い方法はありますか?