0

MVC3 アプリケーションでのエラー処理のために、カスタム エラー セクションで HandleErrorAttribute とカスタム エラー コントローラーを組み合わせて使用​​しています。ロジックは、HandleErrorAttribute の OnException ハンドラーを介してすべての Ajax 要求エラーを処理し、ErrorController を介して残りのエラーを処理することです。以下はコードです -

// Handle any ajax error via HandleErrorAttribute 
public class HandleAjaxErrorAttribute : System.Web.Mvc.HandleErrorAttribute
 {
    public override void OnException(System.Web.Mvc.ExceptionContext filterContext)
    {



        filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
        var exception = filterContext.Exception;

        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            //some logic
            filterContext.ExceptionHandled = true;
        }

    }
}

//Handle remaining errors in the Error Controller

public class ErrorController : Controller
{

    protected override void HandleUnknownAction(string actionName)
    {
        var exception = Server.GetLastError(); //Can't get the exception object here.
        //some logic
    }



}

Web.config 設定:

<customErrors mode="On" defaultRedirect="~/Error">
</customErrors>

ajax 以外の例外が発生すると、制御は OnException ブロックからエラー コントローラーの HandleUnknownAction に流れます。ただし、例外オブジェクトを取得できません。Error Controller で Exception オブジェクトを取得するにはどうすればよいですか?

また、この 2 段階のアプローチは MVC3 でエラーを処理する適切な方法だと思いますか? Application_Error イベント ハンドラーを使用して中央の場所でエラーを処理することを考えましたが、私の調査によると、これは MVC アプリケーションの推奨されるアプローチではありません。

4

3 に答える 3

0

私は間違っているかもしれませんが、MVC がビューで自動的に接続するため、コントローラーのエラー情報について心配する必要はないと思います。したがって、(Razor) ビューを次のように作成すると、動作するはずです。

@model System.Web.Mvc.HandleErrorInfo

任意のログは属性で実行できますが、エラー コントローラーで実行する必要がある場合は、HandleErrorInfo 引数を受け取るエラー コントローラーで LogError アクションを作成し、次のように呼び出します。

@Html.RenderAction("LogError", モデル)

PS私はこれをテストしていませんが、うまくいくはずです。

于 2012-06-13T13:29:20.197 に答える
0

上記のコメントに関して、私が何をしたかを明確にするために、ここにコードを貼り付けています。

このコードは BaseController の内部に入ります (作成することを強くお勧めします。この記事を参照してください: http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1 .aspx )

OnException メソッドをオーバーライドしました (ここでの主な目標は、Ajax 呼び出しと通常の呼び出しを区別することでした)。

protected override void OnException(ExceptionContext filterContext)
    {
        // Set to true or else it'll still propagate
        filterContext.ExceptionHandled = true;

        string message;



        // Check if it's an Ajax request
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            // Here I check if the custom error is on, if it isn't I'll paste the
            // stacktrace and the error
            if (!filterContext.HttpContext.IsCustomErrorEnabled)
            {
                message = filterContext.Exception.Message + filterContext.Exception.StackTrace;
            }
            else
            {
                message = "Something went wrong";
            }

            // TODO: Decide what to do if ajax
            filterContext.HttpContext.Response.StatusCode = 401;
            var json = new JsonResult {Data = message};
            json.ExecuteResult(this.ControllerContext);
        }
        else
        {
            // This is basically the same conditional, but instead of sending a JSON
            // I'll redirect to a view and give it the exception
            if (!filterContext.HttpContext.IsCustomErrorEnabled)
            {
                ViewData.Model = filterContext.Exception;
                this.View("Error").ExecuteResult(this.ControllerContext);
            }
            else
            {
               this.View("../Error/ServerError").ExecuteResult(this.ControllerContext);
            }

        }
    }
}

上記のコメントについて注意すべき重要な点は、CustomError を使用しないと言っているわけではありませんが、実際にパイプラインの外側にあるエラー (401 など) が発生した場合にのみ考えてください。

于 2012-06-13T13:14:35.187 に答える
0

エラーメッセージが表示されず、次の設定を行うまでErrorControllerが起動しませんでした

<customErrors mode="On" defaultRedirect="~/Error">
</customErrors>
于 2013-09-13T15:02:52.607 に答える