Bezdepbonusu7Программирование: статьи и ответы

Вопрос

.NET: какое исключение создавать при отсутствии обязательного параметра конфигурации?

Автор вопроса: Mike HoferОтветов: 11

Вот стандартный сценарий:

if(string.IsNullOrEmpty(Configuration.AppSettings["foobar"]))
   throw new SomeStandardException("Application not configured correctly, bozo.");

Проблема в том, что я не совсем уверен, какое исключение SomeStandardException должно быть.

Я просмотрел платформу 3.5 и нашел двух вероятных кандидатов: _3 _ и ConfigurationErrorsException.

System.Configuration.ConfigurationException

Исключение, которое выдается при возникновении системной ошибки конфигурации.

Замечания

The ConfigurationException exception is thrown if the application attempts to read or write data to the configuration file but is unsuccessful. Some possible reasons for this can include malformed XML in the configuration file, file permission issues, and configuration properties with values that are not valid.

Примечание.

Объект ConfigurationException поддерживается для обратной совместимости. Объект ConfigurationErrorsException заменяет его в системе конфигурации.

Это исключение на самом деле звучит идеально для того, что мне нужно, но оно было помечено как устаревшее, поэтому ixnay on atthay.

Это подводит нас к совершенно загадочному ConfigurationErrorsException:

System.Configuration.ConfigurationErrorsException

Текущее значение не является одним из значений EnableSessionState.

Как видите, его документация совершенно бесполезна. (Так обстоит дело как в локальной, так и в онлайн-справке.) Изучение самого класса показывает, что это решительный перебор для того, что я хочу.

Вкратце, мне нужно стандартное исключение, которое должно выдаваться, когда параметр конфигурации приложения отсутствует или содержит недопустимое значение. Можно подумать, что в Framework есть такое исключение, которое можно использовать в приложениях. (По-видимому, так оно и было, но было помечено как устаревшее и было заменено чем-то гораздо по объему.)

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

Редактировать дополнения

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

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

  • Документация для System.Configuration.ConfigurationErrorsException обновлена. slolife 19.04.2018

exceptionconfiguration

Ответы

Ответ 1 · рейтинг 38 · Dave Swersky

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

Это ваше приложение - пока вы его документируете и четко указываете исключение, которое будет выдано в конкретном случае отсутствующего значения конфигурации, вы можете использовать любое исключение, которое вам нравится. Если вам действительно нужна очень конкретная индикация отсутствующего значения, вы можете подумать о написании собственного исключения ConfigurationSettingMissing:

[Serializable]
public class ConfigurationMissingException : ConfigurationErrorsException
{}

РЕДАКТИРОВАТЬ: написание собственного исключения в этом случае дает дополнительное преимущество, гарантируя, что никогда не будет путаницы в отношении того, откуда исходит исключение - из фреймворка или вашего приложения. Фреймворк никогда не будет генерировать ваши пользовательские исключения.

ОБНОВЛЕНИЕ: я согласен с комментариями, поэтому я изменил подкласс на ConfigurationErrorsException из Exception. Я думаю, что обычно рекомендуется создавать подклассы пользовательских исключений из существующих исключений Framework, где это возможно, избегая класса Exception, если вам не требуется исключение для конкретного приложения.

Ответ 2 · рейтинг 52 · Mark Brackett

Лично я бы использовал InvalidOperationException, поскольку это проблема с состояние объекта, а не система конфигурации. В конце концов, разве вы не должны позволять устанавливать эти параметры с помощью кода, а не конфигурации? Важная часть здесь не в том, что в app.config не было строки, а в том, что не было необходимой информации.

Для меня ConfigurationException (и его замена, ConfigurationErrorsException - несмотря на вводящие в заблуждение документы MSDN) предназначены для ошибок при сохранении, чтении и т. Д. Configuration.

Ответ 3 · рейтинг 18 · Joe

Как сказал Дэниел Ричардсон, следует использовать ConfigurationErrorsException. В общем, рекомендуется создавать свои собственные типы исключений только в том случае, если у вас есть сценарий для их обработки. В случае ошибок конфигурации, которые обычно являются фатальными, это случается редко, поэтому обычно более целесообразно повторно использовать существующий тип ConfigurationErrorsException.

До .NET 2.0 рекомендовалось использовать System.Configuration.ConfigurationException. ConfigurationException устарело в .NET 2.0 по причинам, которые никогда не были мне понятны, и рекомендация была изменена на использование ConfigurationErrorsException.

Я использую вспомогательный метод, чтобы генерировать исключение, чтобы было легко изменить исключение, генерируемое в одном месте при переходе с .NET 1.x на 2.0, или если Microsoft решит снова изменить рекомендацию:

if(string.IsNullOrEmpty(Configuration.AppSettings("foobar")))
{
   throw CreateMissingSettingException("foobar");
}

...

private static Exception CreateMissingSettingException(string name)
{
    return new ConfigurationErrorsException(
        String.Format
        (
        CultureInfo.CurrentCulture,
        Properties.Resources.MissingConfigSetting,
        name
        )
        );
}

Ответ 4 · рейтинг 17 · Laurent

А как насчет _1 _?

Ответ 5 · рейтинг 9 · Daniel Richardson

ConfigurationErrorsException - правильное исключение для описанной вами ситуации. Более ранняя версия документации MSDN для ConfigurationErrorsException имеет больше смысла.

http://msdn.microsoft.com/en-us/library/system.configuration.configurationerrorsexception(VS.80).aspx

Предыдущее резюме и примечания MSDN:

  • Исключение, которое выдается при возникновении ошибки системы конфигурации.
  • Исключение ConfigurationErrorsException выдается, когда возникает какая-либо ошибка во время чтения или записи информации о конфигурации.

Ответ 6 · рейтинг 6 · Gaspar Nagy

Класс ConfigurationElement (который является базовым классом многих классов, связанных с конфигурацией, таких как ConfigurationSection) имеет метод OnRequiredPropertyNotFound (есть и другие вспомогательные методы). Вы можете их назвать.

OnRequiredPropertyNotFound реализован следующим образом:

protected virtual object OnRequiredPropertyNotFound(string name) {
    throw new ConfigurationErrorsException(SR.GetString("Config_base_required_attribute_missing", new object[] { name }), this.PropertyFileName(name), this.PropertyLineNumber(name)); }

Ответ 7 · рейтинг 1 · Charles Bretana

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

в общем, кастомное исключение не требует больших усилий ... вот пример ...

[Serializable]
public class MyCustomApplicationException : ApplicationException
{
    #region privates
    #endregion privates

    #region properties
    #endregion properties

    public MyCustomApplicationException (string sMessage,
        Exception innerException)
        : base(sMessage, innerException) { }
    public MyCustomApplicationException (string sMessage)
        : base(sMessage) { }
    public MyCustomApplicationException () { }

    #region Serializeable Code
    public MyCustomApplicationException (
       SerializationInfo info, StreamingContext context)
        : base(info, context) { }
    #endregion Serializeable Code
}

Ответ 8 · рейтинг 1 · Yogh

Альтернативный метод, который вы могли бы использовать для своих файлов конфигурации, заключался бы в использовании настраиваемых разделов конфигурации вместо AppSettings. Таким образом вы можете указать, что свойство IsRequired и система конфигурации будут выполнять эту проверку за вас. Если свойство отсутствует, оно выдаст ConfigurationErrorsException, поэтому я полагаю, что это подтверждает ответ о том, что вы должны использовать это исключение в своем случае.

Ответ 9 · Hershi

Мое общее правило было бы таким:

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

    выбросить новое исключение ("мое сообщение здесь")

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

Ответ 10 · рейтинг -1 · Matt Jordan

Я склонен не согласиться с предпосылкой вашего вопроса:

Вкратце, мне нужно стандартное исключение, которое должно выдаваться, когда параметр конфигурации приложения отсутствует или содержит недопустимое значение. Можно подумать, что в Framework есть такое исключение, которое можно использовать в приложениях. (По-видимому, так оно и было, но было помечено как устаревшее и было заменено чем-то гораздо более масштабным.)

Согласно документации MSDN по System.Exception (Exception Class , вам действительно не следует генерировать исключения для ошибок ввода пользователя по причинам производительности (на что указали другие в Stack Overflow и в других местах). Это также имеет смысл - почему ваша функция не может вернуть false, если пользовательский ввод введен неправильно, а затем приложение корректно завершает работу? Это скорее проблема дизайна, чем проблема, с которой нужно создать исключение.

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

Ответ 11 · рейтинг -2 · StingyJack

Вы можете попробовать унаследовать исключение XML или просто использовать его.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы