从MVC6/WepApi控制器返回错误字符串

Nic*_*asR 6 c# asp.net asp.net-web-api asp.net-core-mvc

MVC6/WebApi中的模板WebApi控制器实现了一个返回Get方法集合的操作,如下所示:

[HttpGet]
public IEnumerable<MyEntity> Get()
{
    //my code to return entities
}
Run Code Online (Sandbox Code Playgroud)

假设我的代码返回结果会引发异常,我将如何向消费者返回错误消息?

据我所知,异常会导致HTTP 500.这很好,但我想给调用者一个消息,告诉他出了什么问题.由于模板操作的签名,我无法捕获异常并返回一些Http***或ObjectResult实例.

Nko*_*osi 12

您需要自己添加一些代码来处理错误并返回消息.

一种选择是使用异常过滤器并将其全局或在选定的控制器上添加,尽管此方法仅涵盖来自控制器操作方法的异常.例如,以下过滤器仅在请求接受为application/json时返回json对象(否则它将允许异常通过,例如可以由全局错误页面处理):

public class CustomJSONExceptionFilter : ExceptionFilterAttribute
{    
    public override void OnException(ExceptionContext context)
    {
        if (context.HttpContext.Request.GetTypedHeaders().Accept.Any(header => header.MediaType == "application/json"))
        {
            var jsonResult = new JsonResult(new { error = context.Exception.Message });
            jsonResult.StatusCode = Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError;
            context.Result = jsonResult;
        }
    }
}

services.AddMvc(opts => 
{
    //Here it is being added globally. 
    //Could be used as attribute on selected controllers instead
    opts.Filters.Add(new CustomJSONExceptionFilter());
});
Run Code Online (Sandbox Code Playgroud)

另一个选项是您可以更改签名以使响应更灵活.然后,您可以像通常那样处理错误,然后返回用户友好的错误消息.

public IActionResult Get() {
    try {
        IEnumerable<MyEntity> result;
        //...result populated
       return new HttpOkObjectResult(result);
    } catch (Exception ex) {
        //You should handle the error
        HandleError(ex);//the is not an actual method. Create your own.
        //You could then create your own error so as not to leak
        //internal information.
        var error = new 
            { 
                 message = "Enter you user friendly error message",
                 status = Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError
            };
        Context.Response.StatusCode = error.status;            
        return new ObjectResult(error);
    }
}
Run Code Online (Sandbox Code Playgroud)