私は、アプリケーションから発生する可能性のある特定のエラーに基づいてユーザーにリダイレクトを発行せずにビューを返そうとしています、エラーを処理し、ベースコントローラー内にログを記録します、エラーが自分に伝播しないようにしますGlobal.asax-Application_Error()メソッドユーザーは偽のURLを入力しますが、これを回避する方法はありますか?
注:いくつかの問題の回避策があったため、コメント付きのコードを残しました。これは、可能なハンドルに複数の例外があることも示しています...
編集:このOnExceptionオーバーライド内でRedirectToActionを発行すると、すべてが期待どおりに機能しますが、ビューのみを返し、リダイレクトは行いません...
私のベースコントローラーの方法は次のとおりです。
protected override void OnException(ExceptionContext filterContext)
{
//dont interfere if the exception is already handled
if (filterContext.ExceptionHandled)
return;
//let the next request know what went wrong
filterContext.Controller.TempData["exception"] = filterContext.Exception;
//log exception
_logging.Error(User.Identity.Name, ExceptionHelper.BuildWebExceptionMessage(filterContext.Exception));
//set up redirect to my global error handler
//if (filterContext.Exception.GetType() == typeof(NoAccessException))
// filterContext.Result = View(new RouteValueDictionary
// (new { area = "", controller = "Error", action = "PublicError" }));
//else {
//Only return view, no need for redirection
filterContext.Result = View(new RouteValueDictionary
(new { area = "", controller = "Error", action = "NoAccess" }));
//}
//advise subsequent exception filters not to interfere and stop
// asp.net from showing yellow screen of death
filterContext.ExceptionHandled = true;
//erase any output already generated
filterContext.HttpContext.Response.Clear();
//base.OnException(filterContext);
}
このメソッドは、アプリに表示される可能性のある他のエラーを処理する必要があります。上記のエラーがApplication_Error()内で処理されることは望ましくありません。
protected void Application_Error()
{
Exception exception = Server.GetLastError();
// Log the exception.
var logger = Container.Get<ILoggingService>();
logger.Error(User.Identity.Name, ExceptionHelper.BuildWebExceptionMessage(exception));
Response.Clear();
HttpException httpException = exception as HttpException;
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
//if (httpException == null)
//{
routeData.Values.Add("action", "PublicError");
//}
//else //It's an Http Exception, Let's handle it.
//{
// switch (httpException.GetHttpCode())
// {
// case 404:
// // Page not found.
// routeData.Values.Add("action", "HttpError404");
// break;
// case 500:
// // Server error.
// routeData.Values.Add("action", "HttpError500");
// break;
// // Here you can handle Views to other error codes.
// // I choose a General error template
// default:
// routeData.Values.Add("action", "General");
// break;
// }
//}
// Pass exception details to the target error View.
routeData.Values.Add("error", exception);
// Clear the error on server.
Server.ClearError();
// Avoid IIS7 getting in the middle
Response.TrySkipIisCustomErrors = true;
// Call target Controller and pass the routeData.
IController errorController = new ErrorController();
errorController.Execute(new RequestContext(
new HttpContextWrapper(Context), routeData));
}
以下が動作するはずです:
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled)
{
return;
}
filterContext.Result = new ViewResult
{
ViewName = "~/Views/Shared/Error.aspx"
};
filterContext.ExceptionHandled = true;
}
また、このメソッドで例外がスローされないことを確認してください。例外がApplication_Error
。