加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – Web Api 2 – 返回NotFound(); vs使用全局异常处理程

发布时间:2020-12-16 07:06:35 所属栏目:asp.Net 来源:网络整理
导读:我正在开发一个使用.net Web Api 2开发的API.我看过许多关于Web Api版本1的博客帖子和SO问题,但是相比之下,使用版本2中所做的更改的答案似乎很少. 比较这两种处理控制器ItemsController中“错误”的方法 A.使用从System.Web.Http.Results创建对象的方法 // G
我正在开发一个使用.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.

问题

>哪种方式更有意义?
>我应该尝试A&组合B’
>我应该尝试让我的控制器保持稀薄还是应该进行这种类型的验证&因为我可以访问NotFound()和BadRequest()方法,所以处理逻辑会保留在那里吗?
>我应该在框架管道中的其他位置执行此类逻辑吗?

我意识到我的问题更具体系结构,而不是“我如何使用此功能”,但是我还没有找到太多关于如何以及何时使用这些不同功能的解释.

解决方法

从我的角度来看,全局异常处理程序使单元测试每个操作更容易(阅读:更清晰).您现在正在检查特定的[预期]异常与(基本上)比较状态代码. (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);
}

一般来说,我会说这更像是一种偏好,而不是一种强硬的规则,你应该从任何你认为最容易理解和最容易理解的任何东西,从入职的角度(新的眼睛工作项目)和/或以后自己维护.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读