私はVS10でMVC 3のテンプレートプロジェクトを開始し、変更したglobal.asax.csを働いていない HandleErrorAttributeなど
<customErrors mode="On">
が次に作成対応するビューを作成し、最後にDivideByZero-throwをアクションの1つに追加しました。
結果:ビューAllOtherExceptionsがレンダリングされます。
私はVS10でMVC 3のテンプレートプロジェクトを開始し、変更したglobal.asax.csを働いていない HandleErrorAttributeなど
<customErrors mode="On">
が次に作成対応するビューを作成し、最後にDivideByZero-throwをアクションの1つに追加しました。
結果:ビューAllOtherExceptionsがレンダリングされます。
私はダーリンの言うことに同意できませんが、彼は間違っています。
プロパティを設定することに問題はありません(とすると、となります)。
元のコードが期待通りに機能しなかった唯一の理由は、Order
が正しく設定されていないためです。
はMSDNを参照してください:
OnActionExecuting(ActionExecutingContext)、 OnResultExecuting(ResultExecutingContext)、および OnAuthorization(AuthorizationContext)は前方の順序で実行されるフィルタ。 OnActionExecuted(ActionExecutedContext)、 OnResultExecuting(ResultExecutingContext)、および OnException(ExceptionContext)フィルタは、逆の順序で実行されます。
一般的なAllOtherExceptions
フィルタは、最も低い数値のOrder
である必要があります。
うまくいけば、次回も役立ちます。
グローバルアクションフィルタを登録するときは、プロパティを設定しないでください。
public class MyHandleErrorAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if (!filterContext.IsChildAction && (!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled))
{
Exception innerException = filterContext.Exception;
if ((new HttpException(null, innerException).GetHttpCode() == 500))
{
var viewName = "AllOtherExceptions";
if (typeof(DivideByZeroException).IsInstanceOfType(innerException))
{
viewName = "DivideByZeroException";
}
string controllerName = (string)filterContext.RouteData.Values["controller"];
string actionName = (string)filterContext.RouteData.Values["action"];
HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
ViewResult result = new ViewResult
{
ViewName = viewName,
ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
TempData = filterContext.Controller.TempData
};
filterContext.Result = result;
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
}
}
し、それを登録します:カスタムハンドル誤差フィルタを書くことができ
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new MyHandleErrorAttribute());
}
それはもちろん働いた。グローバルアクションフィルタを登録するときにどのようにプロパティを設定できないのですか? – Martin
下記の恐怖の答えをチェックしてください。それが動作すれば確かに簡単です。
数週間後に来て以来、私のフィルタはDarinsレスポンスを使用し、Elmahのレポート機能を組み込んで、thisというトピックのコードで最終的に綴られています。
グローバルアクションフィルタでプロパティを設定できない理由はまだ分かりません。
public class MyHandleErrorAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if (!filterContext.IsChildAction &&
(!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled))
{
var innerException = filterContext.Exception;
if ((new HttpException(null, innerException).GetHttpCode() == 500))
{
var viewName = "GeneralError";
if (typeof (HttpAntiForgeryException).IsInstanceOfType(innerException))
viewName = "SecurityError";
var controllerName = (string) filterContext.RouteData.Values["controller"];
var actionName = (string) filterContext.RouteData.Values["action"];
var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
var result = new ViewResult
{
ViewName = viewName,
ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
TempData = filterContext.Controller.TempData
};
filterContext.Result = result;
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
//From here on down, this is all code for Elmah-reporting.
var version = Assembly.GetExecutingAssembly().GetName().Version;
filterContext.Controller.ViewData["Version"] = version.ToString();
var e = filterContext.Exception;
if (!filterContext.ExceptionHandled // if unhandled, will be logged anyhow
|| RaiseErrorSignal(e) // prefer signaling, if possible
|| IsFiltered(filterContext)) // filtered?
return;
LogException(e);
}
}
}
private static bool RaiseErrorSignal(Exception e)
{
HttpContext context = HttpContext.Current;
if (context == null)
return false;
var signal = ErrorSignal.FromContext(context);
if (signal == null)
return false;
signal.Raise(e, context);
return true;
}
private static bool IsFiltered(ExceptionContext context)
{
var config = context.HttpContext.GetSection("elmah/errorFilter")
as ErrorFilterConfiguration;
if (config == null)
return false;
var testContext = new ErrorFilterModule.AssertionHelperContext(
context.Exception, HttpContext.Current);
return config.Assertion.Test(testContext);
}
private static void LogException(Exception e)
{
HttpContext context = HttpContext.Current;
ErrorLog.GetDefault(context).Log(new Error(e, context));
}
}
あなたは恐怖を持っているように聞こえます!ダーリンは私の問題を解決して以来、あなたはアップフォートでこれを戦わなければならないでしょう。 – Martin
ありがとうございます - 答えになるはずです! –
答えが変更されました... – Martin