MVC6 / WebApi中的模板WebApi控制器实现了一个返回Get方法集合的操作,如下所示:
[HttpGet]
public IEnumerable<MyEntity> Get()
{
//my code to return entities
}
假设我的代码返回结果会抛出异常,我该如何向消费者返回错误消息?
据我所知,异常会导致HTTP 500.这很好,但我想给调用者一个消息,告诉他出了什么问题。由于模板操作的签名,我无法捕获异常并返回一些Http ***或ObjectResult
实例。
答案 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);
}