asp.net – Web Api 2 – 返回NotFound(); vs使用全局异常处理程
我正在开发一个使用.net Web Api 2开发的API.我看过许多关于Web Api版本1的博客帖子和SO问题,但是相比之下,使用版本2中所做的更改的答案似乎很少.
比较这两种处理控制器ItemsController中“错误”的方法 A.使用从System.Web.Http.Results创建对象的方法 // GET api/user/userID/item/itemID [Route("{itemID:int}",Name="GetItem")] [ResponseType(typeof(ItemDTO))] public IHttpActionResult Get(int userID,int itemID) { if (userID < 0 || itemID < 0) return BadRequest("Provided user id or item id is not valid"); ItemDTO item = _repository.GetItem(itemID); if (item == null) return NotFound(); if (item.UserID != userID) return BadRequest("Item userID does not match route userID"); return Ok<ItemDTO>(item); } B.通过注册自定义全局异常处理程序来抛出可以捕获的异常 // ex) in WebApiConfig.cs // config.Services.Replace(typeof(IExceptionHandler),new GlobalExceptionHandler()); public class GlobalExceptionHandler : ExceptionHandler { public override void Handle(ExceptionHandlerContext context) { Exception exception = context.Exception; HttpException httpException = exception as HttpException; if (httpException != null) { context.Result = new SimpleErrorResult(context.Request,(HttpStatusCode)httpException.GetHttpCode(),httpException.Message); return; } if (exception is RootObjectNotFoundException) { context.Result = new SimpleErrorResult(context.Request,HttpStatusCode.NotFound,exception.Message); return; } if (exception is BadRouteParametersException || exception is RouteObjectPropertyMismatchException) { context.Result = new SimpleErrorResult(context.Request,HttpStatusCode.BadRequest,exception.Message); return; } if (exception is BusinessRuleViolationException) { context.Result = new SimpleErrorResult(context.Request,(HttpStatusCode)422,exception.Message); return; } context.Result = new SimpleErrorResult(context.Request,HttpStatusCode.InternalServerError,exception.Message); } } GET api/user/userID/item/itemID [Route("{itemID:int}",int itemID) { if (userID < 0 || itemID < 0) throw new BadRouteParametersException("Provided user or item ID is not valid"); ItemDTO item = _repository.GetItem(itemID); if (item.UserID != userID) throw new RouteObjectPropertyMismatchException("Item userID does not match route userID"); return Ok<ItemDTO>(item); } 这两个看起来都是有效的选择.因为我能够返回System.Web.Http.Results对象,所以似乎解决方案A.是最好的. 但是考虑在我的_repository中我的GetItem方法是这样实现的 public ItemDTO GetItem(int itemId) { ItemInfo itemInfo = ItemInfoProvider.GetItemInfo(itemId); if (itemInfo == null) throw new RootObjectNotFoundException("Item not found"); ItemDTO item = _autoMapper.Map<ItemDTO>(itemInfo); return item; } 在这里,我可以跳过在GetItem中调用null的autoMapper,并跳过在控制器中检查null. 问题 >哪种方式更有意义? 我意识到我的问题更具体系结构,而不是“我如何使用此功能”,但是我还没有找到太多关于如何以及何时使用这些不同功能的解释. 解决方法
从我的角度来看,全局异常处理程序使单元测试每个操作更容易(阅读:更清晰).您现在正在检查特定的[预期]异常与(基本上)比较状态代码. (404 vs. 500 vs. etc)由于您只有一个责任单位,因此更容易更改/记录错误通知(在全球/统一级别).
例如,您更喜欢写哪个单元测试? [Test] public void Id_must_not_be_less_than_zero() { var fooController = new FooController(); var actual = fooController.Get(-1); Assert.IsInstanceOfType(actual,typeof(BadRequestResult)); } [Test] [ExpectedException(typeof(BadRouteParametersException))] public void Id_must_not_be_less_than_zero() { var fooController = new FooController(); var actual = fooController.Get(-1); } 一般来说,我会说这更像是一种偏好,而不是一种强硬的规则,你应该从任何你认为最容易理解和最容易理解的任何东西,从入职的角度(新的眼睛工作项目)和/或以后自己维护. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 为什么当试图保存更改时,GridView行“null”的D
- 敏感词汇过滤DFA算法
- [ASP.net] GridView抓各Field值的方法
- asp.net-core – ASP .NET vNext MVC没有传递给下一个管道?
- 在ASP.NET中更改doctype
- asp.net – WCF – 找到了该合同的多个端点配置 – 错误
- asp.net-mvc – ASP.NET MVC流畅的nNibernate,IoC工具是什么
- asp.net-mvc – 实体框架更新实体以及子实体(必要时添加/更
- ASP.NET设计FTP文件上传的解决方案
- asp.net-mvc – ASP.NET MVC3,Html.TextAreaFor没有编码?