ASP.NET MVC - исключение бросить? - PullRequest
3 голосов
/ 12 октября 2010

У меня есть общий репозиторий - должен ли репозиторий быть в состоянии генерировать исключения или я должен сохранять его тупым?Если я решил выбросить из него исключения, должен ли сервисный уровень затем перехватить его и выдать исключение с более дружественным сообщением, прежде чем оно попадет в контроллер?

  • Pos1: Repository (Throw) => Service(Catch, Throw new) => Контроллер (Catch)
  • Pos2: Репозиторий => Сервис (Throw) => Контроллер (Catch)

Ответы [ 3 ]

2 голосов
/ 13 октября 2010

Должен ли репозиторий быть в состоянии бросить исключения или я должен держать это глупо?

Да - репозиторий должен иметь возможность генерировать исключения. Сохранение чего-то «глупого» не означает, что оно не полностью самоосознанно:)

Предостережение о том, что «исключения должны быть исключительными», по-прежнему применимо - вы можете найти эту статью « Создание более исключительных исключений », которая также имеет отношение к вашему вопросу.

Если я решил бросить исключения из это, если уровень обслуживания тогда поймать его и бросить исключение с более дружеское сообщение, прежде чем оно идет к контроллеру?

Как правило, я не перебрасывал исключения, хотя в этом есть смысл. Прагматичный промежуточный путь - это делать это для типов исключений, которые по какой-то причине вы хотите обработать изящно.

Если вы используете что-то вроде блока регистрации приложений Ms Ent Libs, вы можете установить политику (через конфигурацию), которая позволит вам контролировать то, что происходит, когда возникают исключения - перебрасывать их или иным образом; так что это был бы полезный подход, чтобы прекратить жестко кодировать себя в конкретный результат.

Также это может представлять интерес: Действительно ли существуют исключения для исключительных ошибок?

2 голосов
/ 13 октября 2010

Определенно, Вариант 1.

Я бы также заменил термин «тупой» на «разделение интересов» в вашем мышлении.Нет никаких оснований для тупости хранилища.У него есть работа, и это будет включать исключения.

Это также будет включать в себя их выброс по двум причинам:

  1. Чтобы упаковать реальную ошибку, которая произошла дляпотребляющий код.

  2. Чтобы создать исключение при заданных условиях, которые нарушают то, что вы хотите, чтобы этот класс делал.Эти условия могут не включать исключение, создаваемое платформой, и могут быть связаны исключительно с «интеллектом», который должен иметь ваш репозиторий.

Репозиторий должен включать инкапсуляцию ВСЕХ этого интеллектаоставляя вызывающий код просто необходимо знать, как обращаться с ограниченным набором исключений.В противном случае ваш вызывающий код должен иметь дело, например, с полным набором исключений LINQ, связывая его с технологией, которая должна быть исключительной областью репозитория.

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

То же рассуждение применимо к уровню обслуживания, если он у вас есть.Он должен иметь дело с исключениями точно таким же образом: инкапсулировать «интеллект», который специфичен для его задачи.И снова то же самое происходит с контроллером.Он должен интерпретировать исключения, которые он получает от уровня обслуживания (если он есть), в соответствии с его собственными целями и задачами.

Таким образом, разделение интересов, но никогда не глупость.Даже не Mute: каждый слой должен визжать, когда это необходимо.

1 голос
/ 12 октября 2010

Вообще говоря, вы должны просто вернуть null из своего хранилища, если ваш запрос не возвращает данных. Затем вы можете проверить на нулевое значение в хранилище, если хотите, прежде чем отправлять данные в ваше представление.

public ActionResult Details(int id) {

    Dinner dinner = dinnerRepository.FindDinner(id);

    if (dinner == null)
        return View("NotFound");
    else
        return View("Details", dinner);
}

http://nerddinnerbook.s3.amazonaws.com/Part4.htm

Для редактирования я бы позволил вашему уровню доступа к данным или вашему репозиторию сгенерировать исключение и перехватить его в контроллере, например так:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formValues) {

    Dinner dinner = dinnerRepository.GetDinner(id);

    try {

        UpdateModel(dinner);

        dinnerRepository.Save();

        // Success!
        return RedirectToAction("Details", new { id=dinner.DinnerID });
    }
    catch {

        // Old-school data validation from ASP.NET MVC 1.0
        foreach (var issue in dinner.GetRuleViolations()) {
            ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
        }

        // Return original view, so user can correct errors.
        return View(dinner);
    }
}

http://nerddinnerbook.s3.amazonaws.com/Part5.htm

...