2

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
    // ...
}

...SomethingNotFoundExceptionNotAuthorizedExceptionは 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 エラー ページが表示されます ...

私は何か間違っていますか?おそらくより良い方法はありますか?

4

1 に答える 1

0

いくつかのオプションがあります。

あなたはおそらく欲しい:この男の解決策

あなたはこのようにそれを行うことができますこの男.

すべてのクラスが継承する基本コントローラー クラスを作成し、以下のメソッドを使用することができます。これが私の最後の会社がこの問題に対処した方法です。

protected override void OnException(ExceptionContext filterContext)
{
       Console.WriteLine(filterContext.Exception.ToString());
}
于 2013-02-20T01:29:47.760 に答える