微软的ASP.NET Web API是一个轻量级框架,可用于构建在HTTP上运行的无状态RESTful服务。 异常是在运行时发生的错误,异常处理是在应用程序代码中处理运行时错误的技术。
每个ASP.NET Web API开发人员都应该知道如何处理Web API中的异常以及如何从Web API控制器方法中发送适当的错误代码和错误消息。 我们将在下面的部分中研究如何执行这些任务。
[ 同样在InfoWorld上:如何在ASP.NET Web API中记录请求和响应元数据 ]
在ASP.NET Web API中使用HttpResponseException
您可以使用HttpResponseException类从Web API中的控制器方法返回特定的HTTP状态代码和消息。 这是一个例子。
public Employee GetEmployee(int id)
{
Employee emp = employeeRepository.Get(id);
if (emp == null)
{
var response = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent("Employee doesn't exist", System.Text.Encoding.UTF8, "text/plain"),
StatusCode = HttpStatusCode.NotFound
}
throw new HttpResponseException(response);
}
return emp;
}
如果您的Web API返回IHttpActionResult,则可能要编写GetEmployee方法,如下所示。
public IHttpActionResult GetEmployee(int id)
{
Employee emp = employeeRepository.Get(id);
if (emp == null)
{
var response = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent("Employee doesn't exist", System.Text.Encoding.UTF8, "text/plain"),
StatusCode = HttpStatusCode.NotFound
}
throw new HttpResponseException(response);
}
return Ok(emp);
}
请注意,错误代码和错误消息已分配给响应对象,并且在Web API控制器的操作方法中发生异常时,将返回HttpResponseException的实例。
在ASP.NET Web API中使用HttpError
您可以在Web API控制器方法中使用CreateErrorResponse扩展方法来返回有意义的错误代码和错误消息。 请注意,CreateErrorResponse方法创建一个HttpError对象,然后将其包装在HttpResponseMessage对象中。
下面的代码清单说明了如何使用Web API控制器操作方法中的CreateErrorResponse扩展方法。
public IActionResult GetEmployee(int id)
{
Employee emp = employeeRepository.Get(id);
if (emp == null)
{
string message = "Employee doesn't exist";
throw new HttpResponseException(
Request.CreateErrorResponse(HttpStatusCode.NotFound, message));
}
return Ok(emp);
}
请参考上面显示的GetEmployee()方法。 此方法接受员工ID作为参数,并使用此ID通过员工存储库实例搜索和检索员工记录。 如果找不到具有指定员工ID的员工记录,则将抛出HttpResponseException的实例。 请注意,从Web API控制器方法引发异常实例之前,如何构造适当的错误消息和错误代码。
在ASP.NET Web API中使用异常过滤器
异常过滤器是可用于处理Web API控制器方法中生成的未处理异常的过滤器。 换句话说,您可以使用异常过滤器来捕获Web API中源自控制器方法的未处理异常。 请注意,如果引发了未处理的异常并且未在控制器方法中处理未处理的异常,则全局错误过滤器是在Web API中处理异常的好方法。
要创建异常过滤器,您需要实现IExceptionFilter接口。 您还可以通过扩展抽象类ExceptionFilterAttribute并覆盖OnException方法来创建异常过滤器。 请注意,ExceptionFilterAttribute抽象类又实现了IExceptionFilter接口。
下面的代码片段说明了如何通过扩展ExceptionFilterAttribute类然后覆盖OnException方法来创建自定义异常过滤器。 请注意,自定义异常过滤器如何捕获控制器方法引发的标准异常,然后将它们转换为具有适当HttpStatusCode的HttpStatusResponse对象。
public class CustomExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
HttpStatusCode status = HttpStatusCode.InternalServerError;
String message = String.Empty;
var exceptionType = actionExecutedContext.Exception.GetType();
if (exceptionType == typeof(UnauthorizedAccessException))
{
message = "Access to the Web API is not authorized.";
status = HttpStatusCode.Unauthorized;
}
else if (exceptionType == typeof(DivideByZeroException))
{
message = "Internal Server Error.";
status = HttpStatusCode.InternalServerError;
}
else
{
message = "Not found.";
status = HttpStatusCode.NotFound;
}
actionExecutedContext.Response = new HttpResponseMessage()
{
Content = new StringContent(message, System.Text.Encoding.UTF8, "text/plain"),
StatusCode = status
};
base.OnException(actionExecutedContext);
}
}
您应该将自定义异常过滤器添加到HttpConfiguration对象的过滤器集合中。
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.Filters.Add(new CustomExceptionFilter());
}
您可以通过以下三种方式之一注册异常过滤器:
- 在行动层面
- 在控制器级别
- 全球范围
以下代码段显示了如何在操作级别(即,对控制器操作方法)应用过滤器。
public class EmployeesController : ApiController
{
[NotImplementedExceptionFilter]
public Employee GetEmployee(int id)
{
throw new NotImplementedException();
}
}
要在控制器级别应用异常过滤器,您将需要在类级别使用filter属性,如下所示。
[DatabaseExceptionFilter]
public class EmployeesController : ApiController
{
//Some code
}
您还可以全局应用自定义异常过滤器,以使其适用于所有Web API控制器。 这是您可以执行的操作。
GlobalConfiguration.Configuration.Filters.Add(new DatabaseExceptionFilterAttribute());
以下代码段说明了如何将我们先前创建的自定义异常过滤器应用于控制器方法。
[CustomExceptionFilter]
public IEnumerable<string> Get()
{
throw new DivideByZeroException();
}
ASP.NET Web API支持使用HttpResponseException在控制器级别和操作级别上处理异常。 当Web API中的操作方法引发未捕获的异常时,该异常将转换为HTTP状态码500,即“内部服务器错误”。 如果使用HttpResponseException,则可以在HttpResponseException类的构造函数中指定要返回的状态代码。 这样,您可以自定义错误代码以使它们更有意义。
如何在ASP.NET和ASP.NET Core中执行更多操作:
- 如何在ASP.NET Core中使用内存中缓存
- 如何处理ASP.NET Web API中的错误
- 如何将多个参数传递给Web API控制器方法
- 如何在ASP.NET Web API中记录请求和响应元数据
- 如何在ASP.NET中使用HttpModules
- ASP.NET Core Web API中的高级版本控制
- 如何在ASP.NET Core中使用依赖项注入
- 如何在ASP.NET中使用会话
- 如何在ASP.NET中使用HTTPHandlers
- 如何在ASP.NET Core中使用IHostedService
- 如何在ASP.NET Core中使用WCF SOAP服务
- 如何提高ASP.NET Core应用程序的性能
- 如何使用RestSharp使用ASP.NET Core Web API
- 如何使用ASP.NET Core中的日志记录
- 如何在ASP.NET Core中使用MediatR
- 如何在ASP.NET Core中使用会话状态
- 如何在ASP.NET Core中使用Nancy
- 了解ASP.NET Web API中的参数绑定
- 如何在ASP.NET Core MVC中上传文件
- 如何在ASP.NET Core Web API中实现全局异常处理
- 如何在ASP.NET Core中实施运行状况检查
- ASP.NET中缓存的最佳实践
- 如何在.NET中使用Apache Kafka消息传递
- 如何在Web API上启用CORS
- 何时使用WebClient与HttpClient与HttpWebRequest
- 如何在.NET中使用Redis缓存
- 何时在.NET中使用Task.WaitAll与Task.WhenAll
From: https://www.infoworld.com/article/2994111/how-to-handle-errors-in-aspnet-web-api.html