ServiceStack と ServiceStack.Razor で構築されたアプリケーションがあります。エラー処理を希望どおりに構成するのに問題があります。目標は次のとおりです。
- HttpError w/StatusCode = 401 または 403 は、「アクセスが拒否されました」ページにリダイレクトする必要があります。
- HttpError w/StatusCode = 404 は、「見つかりません」ページにリダイレクトする必要があります。
- それ以外はすべて、一般的なエラー ページにリダイレクトする必要があります。ServiceStack スタイルのエラー メッセージが表示されることは望ましくありません。
まず、401、403、および 404 エラーに対して CustomHttpHandlers を使用してみました。GlobalHtmlErrorHttpHandler を設定して他のエラーをキャプチャするまで、それは機能しました。私が見つけたのは、GlobalHtmlErrorHttpHandler が常に最初にヒットし、すべてのエラーがグローバル エラー ページにリダイレクトされたことです。
次に、GlobalHtmlErrorHttpHandler を削除し、AppHost.ServiceExceptionHandler を使用しました。これは、問題の例外がサービス内からスローされる限り、正常に機能します。サービスの外部でエラーが発生した場合でも、ServiceStack エラー メッセージが表示されます。また、401、403、および 404 エラーが適切な CustomHttpHandler に渡されるように、「エスケープ句」を追加する必要がありました。
そこで、AppHost.ExceptionHandler を設定して、他のすべてをキャプチャします。これは私の AppHost からのスニペットです。これを処理するためのもっと簡単な方法が欠けているように感じます。何か案は?ありがとう!
public override void Configure(Funq.Container container)
{
SetConfig(new EndpointHostConfig
{
DebugMode = false,
AllowFileExtensions = { "swf", "webm", "mp4" },
CustomHttpHandlers =
{
{ HttpStatusCode.Unauthorized, new RazorHandler("/AccessDenied") },
{ HttpStatusCode.Forbidden, new RazorHandler("/AccessDenied") },
{ HttpStatusCode.NotFound, new RazorHandler("/NotFound") }
}
});
// For exceptions occurring within service methods:
this.ServiceExceptionHandler = (req, exc) =>
{
// Allow the error to fall through to the appropriate custom http handler;
// This feels like a kluge.
if (exc is HttpError)
{
IServiceStackHttpHandler handler = null;
if (this.Config.CustomHttpHandlers.TryGetValue(((HttpError)exc).StatusCode, out handler))
{
return new HttpResult() { View = ((RazorHandler)handler).PathInfo.Substring(1) };
}
}
Log.ErrorException(String.Format("Error handling {0}: {1}", req.GetType().FullName, JsonSerializer.SerializeToString(req)), exc);
return new HttpResult() { View = "Error" };
};
// For exceptions outside of service methods:
this.ExceptionHandler = (req, res, op, exc) =>
{
Log.ErrorException(String.Format("Error handling request {0} {1}", op, req.AbsoluteUri), exc);
res.Redirect("~/Error".ToAbsoluteUrl());
};