ServiceStack全局HTML错误处理器配置及视图实现技术咨询
ServiceStack全局HTML错误处理器配置与视图实现问题解答
先把你当前的配置和视图代码整理清楚:
已实现的配置代码
public override void Configure(Container container) { //... this.GlobalHtmlErrorHttpHandler = new RazorHandler("/oops"); this.ServiceExceptionHandlers.Add((httpReq, request, exception) => { //在此处记录异常... //返回自定义响应 return DtoUtils.CreateErrorResponse(request, exception, responseStatus); }); }
错误视图文件(oops.cshtml)代码
@inherits ViewPage<ErrorResponse> @{ ViewBag.Title = "..."; <!-- 这里应该补充完整的视图渲染逻辑,用来展示错误信息 --> }
接下来针对这类配置常见的问题,给你梳理解决方案:
1. 怎么让视图正确拿到错误信息?
你已经让视图继承了ViewPage<ErrorResponse>,这步很对!接下来直接在视图里用Model对象就能访问错误详情了,比如补充视图代码:
@inherits ViewPage<ErrorResponse> @{ ViewBag.Title = "出错啦"; } <div class="container"> <h1>@Model.ResponseStatus.Message</h1> @if (HttpContext.Current.IsDebuggingEnabled) { <pre>@Model.ResponseStatus.StackTrace</pre> } </div>
注意要保证DtoUtils.CreateErrorResponse生成的响应里包含完整的ResponseStatus,最好在异常处理里手动实例化ResponseStatus并传入异常,比如:
var responseStatus = new ResponseStatus(exception); return DtoUtils.CreateErrorResponse(request, exception, responseStatus);
2. 为啥全局HTML错误处理器没触发?
要记住GlobalHtmlErrorHttpHandler只对HTML请求生效,如果是API请求(比如JSON/XML),会直接走ServiceExceptionHandlers返回对应格式的错误。另外还要检查:
/oops对应的视图文件是不是放在正确的目录下(默认是Views或者Pages文件夹)- 有没有自定义路由导致RazorHandler找不到视图
3. 怎么根据异常类型显示不同的错误页面?
可以通过Model.ResponseStatus.ErrorCode来区分异常类型,比如:
@inherits ViewPage<ErrorResponse> @{ ViewBag.Title = Model.ResponseStatus.ErrorCode switch { "Unauthorized" => "无访问权限", "NotFound" => "页面找不到", _ => "系统出错" }; } <div class="container"> @if (Model.ResponseStatus.ErrorCode == "Unauthorized") { <h1>抱歉,您没有权限访问这个页面</h1> <p>请登录后重试</p> } else if (Model.ResponseStatus.ErrorCode == "NotFound") { <h1>404 - 页面不存在</h1> } else { <h1>系统出现了一点小问题</h1> <p>@Model.ResponseStatus.Message</p> } </div>
4. 异常记录的小技巧
在ServiceExceptionHandlers里记录异常时,最好带上请求的上下文信息,方便排查问题,比如:
this.ServiceExceptionHandlers.Add((httpReq, request, exception) => { // 记录请求路径、用户ID、异常栈信息 Log.Error($"请求地址:{httpReq.AbsoluteUri},用户ID:{httpReq.UserAuthId} 发生异常", exception); var responseStatus = new ResponseStatus(exception); return DtoUtils.CreateErrorResponse(request, exception, responseStatus); });
内容的提问来源于stack exchange,提问作者Ermias Y
相关产品推荐
相关产品推荐

