错误处理(将ex.Message发送到客户端)

Bla*_*ell 38 c# asp.net asp.net-web-api asp.net-core asp.net-core-1.0

我有一个ASP.NET Core 1.0 Web API应用程序,并尝试弄清楚如果我的控制器调用的函数错误输出异常消息到客户端.

我尝试了很多东西,但没有实现IActionResult.

我不明白为什么这不是人们需要的常见事情.如果真的没有解决方案可以有人告诉我为什么?

我确实看到了一些使用的文档HttpResponseException(HttpResponseMessage),但为了使用它,我必须安装compat shim.在Core 1.0中有没有新的方法来做这些事情?

这是我一直在尝试使用垫片,但它不起作用:

// GET: api/customers/{id}
[HttpGet("{id}", Name = "GetCustomer")]
public IActionResult GetById(int id)
{
    Customer c = _customersService.GetCustomerById(id);
    if (c == null)
    {
        var response = new HttpResponseMessage(HttpStatusCode.NotFound)
        {
            Content = new StringContent("Customer doesn't exist", System.Text.Encoding.UTF8, "text/plain"),
            StatusCode = HttpStatusCode.NotFound

        };

        throw new HttpResponseException(response);

        //return NotFound();
    }
    return new ObjectResult(c);
}
Run Code Online (Sandbox Code Playgroud)

HttpResponseException抛出时,我查看客户端,无法找到我在内容中发送任何内容的消息.

Set*_*Set 54

这是一个简单的错误DTO类

public class ErrorDto
{
    public int Code {get;set;}
    public string Message { get; set; }

    // other fields

    public override string ToString()
    {
        return JsonConvert.SerializeObject(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后使用ExceptionHandler中间件:

            app.UseExceptionHandler(errorApp =>
            {
                errorApp.Run(async context =>
                {
                    context.Response.StatusCode = 500; // or another Status accordingly to Exception Type
                    context.Response.ContentType = "application/json";

                    var error = context.Features.Get<IExceptionHandlerFeature>();
                    if (error != null)
                    {
                        var ex = error.Error;

                        await context.Response.WriteAsync(new ErrorDto()
                        {
                            Code = <your custom code based on Exception Type>,
                            Message = ex.Message // or your custom message
                            // other custom data
                        }.ToString(), Encoding.UTF8);
                    }
                });
            });
Run Code Online (Sandbox Code Playgroud)

  • 放在它之前.app.UseMVC()在大多数情况下应该是最后一个. (3认同)

sha*_*irh 7

是的,可以将状态代码更改为您需要的任何内容:

在CustomExceptionFilterAttribute.cs文件中,修改代码如下:

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        var exception = context.Exception;
        context.Result = new ContentResult
        {
            Content = $"Error: {exception.Message}",
            ContentType = "text/plain",
            // change to whatever status code you want to send out
            StatusCode = (int?)HttpStatusCode.BadRequest 
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是它.

如果您有自定义异常,那么您也可以在从上下文中获取抛出的异常时检查它们.接下来,您可以发送不同的HTTP状态代码,代替代码中发生的事情.

希望有所帮助.


cvr*_*man 6

您可以创建一个自定义的异常过滤器,如下所示

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        var exception = context.Exception;
        context.Result = new JsonResult(exception.Message);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将以上属性应用于您的控制器.

[Route("api/[controller]")]
[CustomExceptionFilter]
public class ValuesController : Controller
{
     // GET: api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        throw new Exception("Suckers");
        return new string[] { "value1", "value2" };
    }
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*les 5

与其引发和捕获异常,不如将您的操作简化为:

// GET: api/customers/{id}
[HttpGet("{id}", Name = "GetCustomer")]
public IActionResult GetById(int id)
{
    var customer = _customersService.GetCustomerById(id);

    if (customer == null)
    {
        return NotFound("Customer doesn't exist");        
    }

    return Ok(customer);
}
Run Code Online (Sandbox Code Playgroud)

我写了一篇博客文章,其中包含更多选项,例如返回 JSON 对象而不是文本。