NET问答: 如何将 ASP.NET Core WebAPI 中抛出的异常封装成对象?

咨询区

rianjs

在 ASP.NET Core WebAPI 中,我的 Controller 代码如下:


[Route("create-license/{licenseKey}")]
public async Task<LicenseDetails> CreateLicenseAsync(string licenseKey, CreateLicenseRequest license)
{
    try
    {
        // ... controller-y stuff
        return await _service.DoSomethingAsync(license).ConfigureAwait(false);
    }
    catch (Exception e)
    {
        _logger.Error(e);
        const string msg = "Unable to PUT license creation request";
        throw new HttpResponseException(HttpStatusCode.InternalServerError, msg);
    }
}

上面的这段代码如果抛异常了,将返回 http 500 + 自定义错误,我现在有两个疑问:

  • 直接返回错误信息,不想用重量级的 throw new xxx 。

  • 如何将错误处理全局统一化 ?

回答区

peco

如果不想用 throw new 的话,可以把 CreateLicenseAsync() 方法稍微改造一下。

  • 返回值改成 IActionResult

  • throw new 改成 StatusCode

参考代码如下:


[Route("create-license/{licenseKey}")]
public async Task<IActionResult> CreateLicenseAsync(string licenseKey, CreateLicenseRequest license)
{
    try
    {
        // ... controller-y stuff
        return Ok(await _service.DoSomethingAsync(license).ConfigureAwait(false));
    }
    catch (Exception e)
    {
        _logger.Error(e);
        const string msg = "Unable to PUT license creation request";
        return StatusCode((int)HttpStatusCode.InternalServerError, msg)
    }
}

如果你想把 错误处理 应用到全局,可以在 中间件 中实现异常的统一处理。

先定义一个 ExceptionMiddleware 中间件。


public class ExceptionMiddleware
{
    private readonly RequestDelegate _next;

    public ExceptionMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            context.Response.ContentType = "text/plain";
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            await context.Response.WriteAsync(ex.Message);    
        }
    }
}

接下来将其注入到 request pipeline 中即可。


    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
    {
        app.UseMiddleware<ExceptionMiddleware>();
        app.UseMvc();
    }

点评区

asp.net core 的统一异常信息处理,这种功能真的太实用了,刚好最近做的新项目也搭配进去了,不过我到没有使用 Middleware ,而是模仿 asp.net 时代的 异常过滤器 实现,参考代码如下:


    /// <summary>
    /// 全局异常处理
    /// </summary>
    public class IbsExceptionFilter : ExceptionFilterAttribute
    {
        public override Task OnExceptionAsync(ExceptionContext context)
        {
            context.ExceptionHandled = true;

            HttpResponse response = context.HttpContext.Response;

            response.StatusCode = 200;

            response.ContentType = "application/json";

            var message = context.Exception.Message;

            context.Result = new JsonResult(ApiResponse.Err(message));

            return Task.CompletedTask;
        }
    }

然后我在 ConfigureServices() 中做了一个全局注册,参考代码如下:


    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers(config => { config.Filters.Add(new IbsExceptionFilter()); });
    }

这种方式也是可以搞定的,实现方式多种多样,以此纪念一下????????????

原文链接:https://stackoverflow.com/questions/43358224/how-can-i-throw-an-exception-in-an-asp-net-core-webapi-controller-that-returns-a

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值