【问题标题】:Custom error pages in servicestackservicestack 中的自定义错误页面
【发布时间】:2014-10-05 05:14:38
【问题描述】:

如何配置 ServiceStack 以根据返回的错误类型提供特定的错误页面(404、500 等)?

目前,我正在使用以下代码的 RawHttpHandler 来确保对 HTML 文件的请求经过身份验证。但是,如果用户指定了一个不存在的文件或端点,我怎样才能让它返回我的 404.html 页面。

  this.RawHttpHandlers.Add(httpReq =>
            {
                var session = httpReq.GetSession();

                if(!session.IsAuthenticated) {
                    var isHtmlFileRequest = httpReq.PathInfo.EndsWith(".html");

                    if(isHtmlFileRequest && !files.Any(s => httpReq.PathInfo.ToLower().Contains(s))) {
                        return new RedirectHttpHandler {
                            AbsoluteUrl = "/Login.html"
                        };
                    }
                }

                return null;
            });

【问题讨论】:

    标签: servicestack


    【解决方案1】:

    Error Handling wiki 在 ServiceStack 中显示了与 Customize Handling of Exceptions 不同的方式,例如,您可以将 404 错误重定向到 /404.cshtml

    public override void Configure(Container container)
    {
        this.CustomHttpHandlers[HttpStatusCode.NotFound] = 
            new RazorHandler("/404");
    }
    

    CustomHttpHandlers 可以是任何IServiceStackHandler,它只是一个支持 ASP.NET 和 HttpListener 请求的 HttpHandler。创建一个最简单的方法是从IServiceStackHandler 继承。这是一个类似于StaticFileHandler 的自定义静态文件处理程序的示例,只是它只写入指定的filePath 而不是使用HTTP 请求路径:

    public class CustomStaticFileHandler : HttpAsyncTaskHandler
    {
        string filePath;
        public CustomStaticFileHandler(string filePath)
        {
            this.filePath = filePath;
        }
    
        public override void ProcessRequest(HttpContextBase context)
        {
            var httpReq = context.ToRequest(GetType().GetOperationName());
            ProcessRequest(httpReq, httpReq.Response, httpReq.OperationName);
        }
    
        public override void ProcessRequest(IRequest request, IResponse response, 
            string operationName)
        {
            response.EndHttpHandlerRequest(skipClose: true, afterHeaders: r =>
            {
                var file = HostContext.VirtualPathProvider.GetFile(filePath);
                if (file == null)
                    throw new HttpException(404, "Not Found");
    
                r.SetContentLength(file.Length); 
                var outputStream = r.OutputStream;
                using (var fs = file.OpenRead())
                {
                    fs.CopyTo(outputStream, BufferSize);
                    outputStream.Flush();
                }            
            }
        }
    }
    

    然后可以正常注册,即:

    public override void Configure(Container container)
    {
        this.CustomHttpHandlers[HttpStatusCode.NotFound] = 
            new CustomStaticFileHandler("/404.html");
    }
    

    【讨论】:

    • 谢谢。我以前见过,但不确定如何在没有 Razor 的情况下使其工作。我必须安装 Razor 软件包吗?我暂时不用。
    • 换句话说,是否有文件处理程序或我可以用来简单地提供 html 文件的东西?
    • @theoutlander 是的 RazorHandler 需要 ServiceStack.Razor NuGet 包。我已经用一个显示如何提供静态文件的示例更新了答案。
    • 我将自定义处理程序与验证资源授权的代码结合在一起。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 2011-06-11
    • 2014-06-24
    • 2017-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多