Как избежать использования try ... catch в контроллерах? - PullRequest
4 голосов
/ 04 января 2012

Я пытаюсь обработать свои исключения на нижних уровнях моего приложения, так как они могут быть обработаны (регистрируя их). Однако существуют ошибки, которые должны приводить к сбою приложения, например, если параметр имеет значение NULL и не должен в этом случае выдавать исключение ArgumentNullException.

Если принять во внимание уровень контроллера, который вызывает уровень обслуживания. Я хочу, чтобы сервисный уровень не генерировал исключения, потому что я хочу обрабатывать их все здесь (ведение журнала), но я упал, как будто это невозможно в таком случае (например, в случае NULL).

Так каков наилучший способ избежать использования try ... catch в контроллерах? или я действительно должен использовать try ... catch в контроллере?

Ответы [ 2 ]

8 голосов
/ 04 января 2012

Я предпочитаю обрабатывать все необработанные исключения (вещи, которые не должны происходить) в методе Application_Error . Это место, где вы можете записать исключение и в зависимости от его характера показать правильное представление об ошибке.

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

Для всего, что я собираюсь обрабатывать, например, бизнес-ошибки и т. Д., Нет ничего плохого в использовании try / catch или даже лучше в использовании операторов if, и сервисный уровень уведомляет вас о том, что какая-то операция прошла успешно или не удалась ( TryXXX шаблон.)

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

3 голосов
/ 04 января 2012

Сотрудничать в ответе Дарина Димитрова

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

Это то, что я предпочитаю. Вы можете создать IExceptionFilter , который будет выглядеть следующим образом:

public class ExceptionLoggingFilter : IExceptionFilter
{
    private ILogger _logger;

    public ExceptionLoggingFilter(ILogger logger)
    {
        _logger = logger;
    }

    public void OnException(ExceptionContext context)
    {
        Exception ex = context.Exception;

        if (_logger != null)
        {
            _logger.log(ex)
        }
    }
    context.ExceptionHandled = true; //see note
}

примечание: если вы не хотите сбрасывать исключение, вы можете добавить его. Если вы хотите только войти, но у вас есть другой фильтр для обработки, вы можете удалить эту строку.

тогда в вашем Global.aspx вы сделаете:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new ExceptionLoggingFilter(new Log4NetLogger()));
}

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

...