我有一个使用 ServiceStack 和 ServiceStack.Razor 构建的应用程序。我无法按照我想要的方式配置错误处理。这是目标:
- HttpError w/StatusCode = 401 或 403 应重定向到“拒绝访问”页面。
- HttpError w/StatusCode = 404 应重定向到“未找到”页面。
- 其他所有内容都应重定向到通用错误页面。我们不希望显示任何 ServiceStack 样式的错误消息。
首先,我尝试使用 CustomHttpHandlers 处理 401、403 和 404 错误。这一直有效,直到我设置 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());
};