咨询区
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