Как я могу обнаружить ошибки синтаксиса значения в файлах app.config? - PullRequest
2 голосов
/ 10 февраля 2012

Мне нужно улучшить сообщение об ошибках в файлах app.config.

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

Файл My Settings.Designer.cs (сгенерированный Visual Studio):

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute(
    "Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {

    private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

    public static Settings Default { get { return defaultInstance; } }

    [global::System.Configuration.UserScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Configuration.DefaultSettingValueAttribute("17")]
    public int SecondSetting
    {
        get { return ((int)(this["SecondSetting"])); }
        set { this["SecondSetting"] = value; }
    }
}

My C # тестовое приложение:

static void Main (string[] args)
{
    try
    {
        Console.WriteLine(AppConfigTests.Properties.Settings.Default.SecondSetting);
    }
    catch (Exception x)
    {
        Console.WriteLine(x.ToString());
    }
}

Соответствующая часть моего файла App.config (обратите внимание, что значение не является допустимым целым числом):

<userSettings>
    <AppConfigTests.Properties.Settings>
        <setting name="SecondSetting" serializeAs="String">
            <value>1foo7</value>
        </setting>
    </AppConfigTests.Properties.Settings>
</userSettings>

Исключение System.Format вызывается System.Number.StringToNumber, но что-то перехватывает его и выбрасывает, и мой блок catch никогда не вводится. В выходных данных отладчика Visual Studio я обнаружил «Первое случайное исключение типа« System.FormatException »произошло в mscorlib.dll», но это не помогло мне, кроме как для дальнейшего подтверждения того, что возникло исключение.

Я попытался добавить IntegerValidatorAttribute к своему свойству настройки в Settings.Designer.cs, но это не помогло (и я убедился, что .cs не был восстановлен).

Я попытался добавить следующий код в начало моего метода main (), но это тоже не помогло:

foreach (SettingsProperty sp in AppConfigTests.Properties.Settings.Default.Properties)
    sp.ThrowOnErrorDeserializing = true;

Я думал о реализации своего собственного ConfigurationSection, но я надеюсь, что есть более простое решение.

Просто повторюсь: мне нужен способ сообщать об ошибках в значениях настроек в файлах app.config.

(Если я нарушу синтаксис XML в App.config (например, удалив угловую скобку), мой блок catch получит приятное исключение со всеми подробностями, которые я мог бы попросить.)

1 Ответ

1 голос
/ 13 июня 2013

Вы можете сделать это следующим образом (при условии, что все значения параметров переопределены в app.config):

  foreach (SettingsPropertyValue propertyValue in AppConfigTests.Properties.Settings.Default.PropertyValues) {
    if (propertyValue.UsingDefaultValue) {
      throw new Exception(propertyValue.Name + " is not deserialized properly.");
    }
  }

Если вы пишете веб-приложение, оно запускает это событие, когда десериализация не удается:

try {
  if (this.IsHostedInAspnet()) {
    object[] args = new object[] { this.Property, this, ex };
    Type type = Type.GetType("System.Web.Management.WebBaseEvent, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", true);
    type.InvokeMember("RaisePropertyDeserializationWebErrorEvent", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, null, args, CultureInfo.InvariantCulture);
  }
}
catch {
}

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

...