将异常作为JSON消息返回

Hin*_*ich 7 .net asp.net-core-mvc asp.net-core

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

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

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

Nat*_*ini 6

您正在寻找异常过滤器(作为属性或全局过滤器).来自文档:

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

如果您希望将任何未处理的异常作为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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options =>
    {
        options.Filters.Add(typeof(JsonExceptionFilter));
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 注意,Exception过滤器只处理MVC异常,ASP.NET Core中更通用的方法是使用ExceptionHandler中间件:http://stackoverflow.com/documentation/asp.net-core/1479/middleware/4815/using-the-的ExceptionHandler中间件以发送定制-JSON-错误到客户端#吨= 201608011043382097082 (3认同)

Hin*_*ich 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 
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 为消息创建类编写一个简单的类,该类表示要在任何错误情况下作为请求发送的JSON错误消息的实例:

    public class ExceptionMessageContent
    {
    
        public string Error { get; set; }
        public string Message { get; set; }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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" );
    
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

现在,当我想在任何地方抛出错误时,我都可以这样做。该请求将重定向到错误处理程序,并发送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 );
Run Code Online (Sandbox Code Playgroud)