从MVC6 / WepApi控制器

时间:2016-03-09 01:20:24

标签: c# asp.net-web-api asp.net-core-mvc

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

[HttpGet]
public IEnumerable<MyEntity> Get()
{
    //my code to return entities
}

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

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

5 个答案:

答案 0 :(得分: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());
});

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

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);
    }
}

答案 1 :(得分:2)

将您的方法更改为

[HttpGet]
[ResponseType(typeof(IEnumerable<MyEntity>))]
public IHttpActionResult Get()
{
    //when ok
    return Ok(response); // response is your IEnumerable<MyEntity>

    //when error
    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.WhateverStatusCodeSuitable)
            {
                ReasonPhrase = "your message"
            });

}

答案 2 :(得分:1)

就像你要保持任何程序一样运行。

try {
    ...
} catch (Exception e) {
    return errorMessageView;
}

或者,您可以使用HandleErrorAttribute

答案 3 :(得分:1)

迁移的时间稍晚一些,但是现在使用自定义代码获取自定义错误的最佳方法似乎是使用StatusCode方法。

` [HttpGet("{id}")]
[ProducesResponseType(typeof(IEnumerable<string>), 200)]
[ProducesResponseType(typeof(void), 404)]
public IActionResult Get(int id)
{
    Product product = null;
    if (!this.productRepository.TryGet(id, out product))
    {
        return StatsusCode(500, "NotFound");
    }

    return Ok(product);
}`

答案 4 :(得分:0)

你可以乱用异常,但我得到的印象是我们不应该再那么想了。这似乎是MVC6的禅宗:

    [HttpGet("{id}")]
    [ProducesResponseType(typeof(IEnumerable<string>), 200)]
    [ProducesResponseType(typeof(void), 404)]
    public IActionResult Get(int id)
    {
        Product product = null;
        if (!this.productRepository.TryGet(id, out product))
        {
            return NotFound();
        }

        return Ok(product);
    }