ASP.NET MVC - Где бросить исключения?

Лучшая практика для исключения исключений, если запись не найдена в db?

// CONTROLLER
public ActionResult Edit(int categoryId, int id)
{
    Product target = Products.GetById(id);
    if (target == null) throw new HttpException(404, "Product not found");

    return View("Edit", target);
}

// REPOSITORY
public Product GetById(int id)
{
    return context.Products.FirstOrDefault(x => x.productId == id);
}

или

// CONTROLLER
public ActionResult Edit(int categoryId, int id)
{
    return View("Edit", Products.GetById(id));
}

// REPOSITORY
public Product GetById(int id)
{
    Product target = context.Products.FirstOrDefault(x => x.productId == id);
    if (target == null) throw new HttpException(404, "Product not found with given id");

    return target;
}

Ответы

Ответ 1

Никогда не бросайте HttpException из репозитория... это неправильный уровень абстракции. Если вы не хотите, чтобы ваш репозиторий возвращал null, выполните следующие действия:

// CONTROLLER
public ActionResult Edit(int categoryId, int id)
{
    try {
       Product target = Products.GetById(id);
    }
    catch(ProductRepositoryException e) {
       throw new HttpException(404, "Product not found")
    }

    return View("Edit", target);
}

// REPOSITORY
public Product GetById(int id)
{
    Product target = context.Products.FirstOrDefault(x => x.productId == id);
    if (target == null) throw new ProductRepositoryException();

    return target;
}

Ваш репозиторий не должен знать ничего о HTTP, но ваш контроллер может узнать о репозитории. Таким образом, вы выбрасываете исключение репозитория из репозитория и "переводите" его в исключение HTTP в контроллере.

Ответ 2

Не бросайте исключение HttpException в репозиторий, так как вы можете повторно использовать этот код в будущем в среде, отличной от Http. Выбросьте свое собственное исключение ItemNotFound, если вам требуется хотя бы один элемент и обработать это исключение в контроллере или вернуть значение null и обработать это.

Ответ 3

Я бы бросил HttpException в контроллер и вернул null из репозитория.