我在WebAPI中有很多控制器方法,类似于以下内容:
public IHttpActionResult Delete(int id)
{
var command = new DeleteItemCommand() { Id = id };
try
{
_deleteCommandHandler.Handle(command);
}
catch (CommandHandlerResourceNotFoundException)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
catch(CommandHandlerException)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
// More catches etc...
return Ok();
}
命令处理程序(在本例中为_deleteCommandHandler
)在执行的早期注入,命令可以在方法中构建,也可以使用WebApi的自动方法构建。
我想要做的是在私有方法中封装try / catch错误处理,最后得到类似于的控制器:
public IHttpActionResult Delete(int id)
{
var command = new DeleteItemCommand() { Id = id };
return ExecuteCommand(x => _deleteCommandHandler.Handle(command));
}
我不确定私有ExecuteCommand
方法的签名应该是什么。
答案 0 :(得分:1)
我认为您可以通过以下方式Invoke
采取行动:
public IHttpActionResult Delete(int id)
{
return ExecuteCommand(() => {
var command = new DeleteItemCommand() { Id = id };
_deleteCommandHandler.Handle(command);
});
}
private IHttpActionResult ExecuteCommand(Action action)
{
try
{
action.Invoke();
//or: action();
}
catch (CommandHandlerResourceNotFoundException)
{
return HttpResponseException(HttpStatusCode.NotFound);
}
catch (CommandHandlerException)
{
return HttpResponseException(HttpStatusCode.InternalServerError);
}
return Ok();
}
HttpResponseException的一个很好的参考。
答案 1 :(得分:0)
我会创建一个自定义错误处理程序过滤器,并以集中形式处理所有可能的错误。这样你就可以从动作方法中抛出任何异常,然后它们将被捕获到你可以处理它们的过滤器并相应地改变响应。
public class NotImplExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is NotImplementedException)
{
context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
}
}
}
该示例取自this article,您可以在其中更详细地找到该概念。
答案 2 :(得分:0)
这是一个类似于shA.t的答案的解决方案,但异常映射在字典中,而try / catch逻辑在扩展方法中:
public class TestController:ApiController
{
public IHttpActionResult Delete(int id)
{
return ExecuteCommand(() => {
var command = new DeleteItemCommand() { Id = id };
_deleteCommandHandler.Handle(command);
});
}
private IHttpActionResult ExecuteCommand(Action action)
{
return action.SafeInvoke();
}
}
public static class ActionExtensions
{
private static readonly Dictionary<Type, HttpStatusCode> _exceptionToStatusCodeLookup = new Dictionary<Type, HttpStatusCode>
{
{typeof(CommandHandlerResourceNotFoundException), HttpStatusCode.NotFound },
{typeof(CommandHandlerException), HttpStatusCode.InternalServerError },
};
public static IHttpActionResult SafeInvoke(this Action action)
{
try
{
action();
}
catch (Exception ex)
{
var statusCode = _exceptionToStatusCodeLookup.ContainsKey(ex.GetType()) ? _exceptionToStatusCodeLookup[ex.GetType()] : HttpStatusCode.InternalServerError;
return new HttpResponseException(statusCode);
}
return new OkResult();
}
}