将异常作为JSON消息返回

时间:2016-07-29 17:15:06

标签: .net asp.net-core asp.net-core-mvc

我正在使用ASP.NET Core开发API,我正在努力处理异常处理。

当发生任何异常时,或者在我想要返回具有不同状态代码的自定义错误的任何控制器中时,我想返回JSON格式的异常报告。我在错误响应中不需要HTML。

我不确定是否应该使用中间件或其他内容。我应该如何在ASP.NET Core API中返回JSON异常?

2 个答案:

答案 0 :(得分:6)

您正在寻找异常过滤器(作为属性或全局过滤器)。来自docs

  

异常过滤器处理未处理的异常,包括在控制器创建和模型绑定期间发生的异常。只有在管道中发生异常时才会调用它们。他们可以提供单一位置来在应用程序中实现常见的错误处理策略。

如果您希望任何未处理的异常作为JSON返回,这是最简单的方法:

public class JsonExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        var result = new ObjectResult(new
        {
            code = 500,
            message = "A server error occurred.",
            detailedMessage = context.Exception.Message
        });

        result.StatusCode = 500;
        context.Result = result;
    }
}

您可以自定义响应以添加任意数量的详细信息。 ObjectResult将被序列化为JSON。

在启动时将过滤器添加为MVC的全局过滤器:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Filters.Add(typeof(JsonExceptionFilter));
    });
}

答案 1 :(得分:5)

好的,我有一个有效的解决方案,我很满意。

  1. 添加中间件: 在Configure方法中,注册中间件(ASP.NET Core附带)。

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        // logging stuff, etc.
    
        app.UseStatusCodePagesWithReExecute("/error/{0}");
        app.UseExceptionHandler("/error");
    
        app.UseMvc(); // if you are using Mvc
    
        // probably other middleware stuff 
    }
    
  2. 为消息创建一个类 在任何错误情况下,编写一个简单的类,表示要作为请求发送的 JSON错误消息的实例:

    public class ExceptionMessageContent
    {
    
        public string Error { get; set; }
        public string Message { get; set; }
    
    }
    
  3. 创建错误控制器 添加处理所有预期和意外错误的错误控制器。请注意,这些路由对应于中间件配置。

    [Route("[controller]")]
    public class ErrorController : Controller
    {
    
        [HttpGet]
        [Route("")]
        public IActionResult ServerError()
        {
    
            var feature = this.HttpContext.Features.Get<IExceptionHandlerFeature>();
            var content = new ExceptionMessageContent()
            {
                Error = "Unexpected Server Error",
                Message = feature?.Error.Message
            };
            return Content( JsonConvert.SerializeObject( content ), "application/json" );
    
        }
    
    
        [HttpGet]
        [Route("{statusCode}")]
        public IActionResult StatusCodeError(int statusCode)
        {
    
            var feature = this.HttpContext.Features.Get<IExceptionHandlerFeature>();
            var content = new ExceptionMessageContent() { Error = "Server Error", Message = $"The Server responded with status code {statusCode}" };
            return Content( JsonConvert.SerializeObject( content ), "application/json" );
    
        }
    }
    
  4. 现在,当我想在任何地方抛出错误时,我可以这样做。请求被重定向到错误处理程序并发送带有格式错误消息的500。此外,404和其他代码也可以优雅地处理。我想发送的任何自定义状态代码,我也可以使用ExceptionMessageContent的实例返回它们,例如:

    // inside controller, returning IActionResult
    
    var content = new ExceptionMessageContent() { 
        Error = "Bad Request", 
        Message = "Details of why this request is bad." 
    };
    
    return BadRequest( content );