【问题标题】:ServiceExceptionHandler usage on RestServiceBase<T>RestServiceBase<T> 上的 ServiceExceptionHandler 用法
【发布时间】:2025-12-21 11:15:06
【问题描述】:

我正在尝试在我的服务上使用ServiceExceptionHandler,它扩展了RestServiceBase&lt;TViewModel&gt;

我可以使用AppHost.ServiceExceptionHandler,效果很好。我需要来自HttpRequest 的用户信息,这在 AppHost 级别不可用。

所以我尝试在服务级别使用ServiceExceptionHandler。虽然我在服务ctor 上设置了委托,但在OnGet 方法上抛出异常时它是null

public class StudentService : RestServiceBase<Student>
{ 
    public StudentService()
    {
        ServiceExceptionHandler = (request, exception) =>
        {
            logger.Error(string.Format("{0} - {1} \n Request : {2}\n", HttpRequest.UserName(), exception.Message, request.Dump()), exception);
            var errors = new ValidationErrorField[] { new ValidationErrorField("System Error", "TODO", "System Error") };
            return DtoUtils.CreateErrorResponse("System Error", "System Error", errors);
        };
    }
}

我不确定这段代码有什么问题。任何帮助将不胜感激。

【问题讨论】:

    标签: servicestack


    【解决方案1】:

    注册全局 AppHost.ServiceExceptionHandler

    在您的AppHost.Configure() 中,您可以注册一个全局异常处理程序:

    this.ServiceExceptionHandler = (request, ex) => {
       ... //handle exception and generate your own ErrorResponse
    };
    

    对于更细粒度的异常处理程序,您可以覆盖以下自定义服务事件挂钩:

    使用新 API 处理异常

    如果您使用New API,您可以通过提供自定义运行器来覆盖异常,例如:

    public class AppHost { 
      ...
        public virtual IServiceRunner<TRequest> CreateServiceRunner<TRequest>(
            ActionContext actionContext)
        {           
            //Cached per Service Action
            return new ServiceRunner<TRequest>(this, actionContext); 
        }
    }
    
    public class MyServiceRunner<T> : ServiceRunner<T> {
        public override object HandleException(
            IRequestContext requestContext, TRequest request, Exception ex) {
          // Called whenever an exception is thrown in your Services Action
        }
    }
    

    使用旧 API 处理异常

    RestServiceBase&lt;T&gt; 使用旧 API,您可以在其中通过覆盖 HandleException 方法来处理错误,例如:

    public class StudentService : RestServiceBase<Student>
    { 
        ...
    
        protected override object HandleException(T request, Exception ex)
        {
            LogException(ex);
    
            return base.HandleException(request, ex);
        }
    } 
    

    【讨论】: