2017-04-12 47 views
4

在框架的WebAPI 2,我有一个控制器,它看起来像这样:如何在返回对象的ASP.NET Core WebAPI控制器中引发异常?

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

果然,我得到一个500错误与消息。

如何在ASP.NET Core Web API中执行类似操作?

HttpRequestException似乎并不存在。我宁愿继续返回对象而不是HttpRequestMessage

回答

5

这样的事情呢。创建一个中间件在那里你会暴露出某些异常消息:

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; 

      if (ex is ApplicationException) 
      { 
       await context.Response.WriteAsync(ex.Message); 
      } 
     } 
    } 
} 

用它在你的应用程序:

app.UseMiddleware<ExceptionMiddleware>(); 
app.UseMvc(); 

,然后在动作抛出异常:

[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 ApplicationException(msg); 
    } 
} 

一个更好的办法将返回IActionResult。这样你就不必抛出异常。像这样:

[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) 
    } 
} 
+0

是的,这个明确的“中间件”概念似乎是常规框架和Core之间的区别。我想我认为这将是一个简单的提升和放弃,但不完全。我在这里看到了类似的方法:https://weblog.west-wind.com/posts/2016/oct/16/error-handling-and-exceptionfilter-dependency-injection-for-aspnet-core-apis – rianjs

3

最好不要在每个动作中都捕捉到所有异常。只需要捕捉异常情况,您需要专门做出反应并捕获(并将其包装到HttpResponse中)所有其余的在Middleware中。