it-swarm.com.de

.NET: Welche Ausnahme muss ausgelöst werden, wenn eine erforderliche Konfigurationseinstellung fehlt?

Hier ist ein Standardszenario:

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

Das Problem ist, ich bin nicht ganz sicher, welche Ausnahme SomeStandardException sein sollte.

Ich habe das 3.5 Framework durchgesehen und zwei mögliche Kandidaten gefunden: ConfigurationException und ConfigurationErrorsException .

System.Configuration.ConfigurationException

Die Ausnahme, die ausgelöst wird, wenn ein Konfigurationssystemfehler aufgetreten ist.

Bemerkungen

Die Ausnahme ConfigurationException wird ausgelöst, wenn die Anwendung versucht, Daten in die Konfigurationsdatei zu lesen oder zu schreiben, dies jedoch nicht erfolgreich ist. Einige mögliche Gründe hierfür können fehlerhaftes XML in der Konfigurationsdatei, Dateiberechtigungsprobleme und Konfigurationseigenschaften mit ungültigen Werten sein.

Hinweis:

Das Objekt ConfigurationException wird aus Gründen der Abwärtskompatibilität beibehalten. Das Objekt ConfigurationErrorsException ersetzt es für das Konfigurationssystem.

Diese Ausnahme klingt eigentlich perfekt für das, was ich brauche, aber sie wurde als veraltet markiert.

Dies bringt uns zu dem gründlich rätselhaften ConfigurationErrorsException :

System.Configuration.ConfigurationErrorsException

Der aktuelle Wert ist keiner der EnableSessionState-Werte.

Wie Sie sehen können, ist die Dokumentation völlig nutzlos. (Dies ist sowohl in der lokalen als auch in der Online-Hilfe der Fall.) Eine Untersuchung der Klasse selbst zeigt, dass es für das, was ich möchte, ein drastischer Overkill ist.

Kurz gesagt, ich benötige eine Standardausnahme, die ausgelöst werden sollte, wenn eine Anwendungskonfigurationseinstellung fehlt oder einen ungültigen Wert enthält. Man könnte meinen, das Framework enthält eine solche Ausnahme, die von Anwendungen verwendet werden kann. (Anscheinend hat es funktioniert, aber es wurde als veraltet markiert und durch etwas ersetzt viel größeres.)

Welche Lösungen, wenn überhaupt, nutzt ihr dafür, und muss ich sie aufsaugen und meine eigene Ausnahme dafür aufrollen?

Addenda bearbeiten

Einige haben gefragt, ob ich einen Standardwert bereitstellen und fortfahren könnte. In bestimmten Fällen, ja, und in diesen Fällen würde die Ausnahme nicht ausgelöst. Für bestimmte Einstellungen gilt dies jedoch nicht. Zum Beispiel: Namen und Anmeldeinformationen von Datenbankservern, Authentifizierungsserver und Pfade zu installierten Anwendungen von Drittanbietern.

Es ist auch erwähnenswert, dass die Anwendung, an der ich hauptsächlich arbeite, eine Konsolenanwendung ist, die im Batch-Modus ausgeführt wird, und ich möchte, dass sie eine Ausnahme auslöst, die von der Hauptmethode abgefangen und entsprechend protokolliert wird, wenn das Ding nicht entsprechend konfiguriert ist. (Es ist Legacy-Code, den ich geerbt habe, und momentan ist nur angenommen alles peachy.)

115
Mike Hofer

Sie sind in Ihrer Ausnahmebedingung nicht auf vorhandene Ausnahmen im Framework beschränkt. Wenn Sie vorhandene Ausnahmen verwenden möchten, müssen Sie die Dokumentation nicht unbedingt genau befolgen. In der Dokumentation wird beschrieben, wie das Framework eine bestimmte Ausnahme verwendet, ohne jedoch darauf beschränkt zu sein, wie Sie eine vorhandene Ausnahme verwendet/wiederverwendet.

Es ist Ihre Anwendung. Solange Sie sie dokumentieren und klar angeben, welche Ausnahme im konkreten Fall eines fehlenden Konfigurationswerts ausgelöst wird, können Sie eine beliebige Ausnahme verwenden. Wenn Sie eine sehr genaue Angabe eines fehlenden Werts wünschen, können Sie eine eigene ConfigurationSettingMissing-Ausnahme erstellen:

[Serializable]
public class ConfigurationMissingException : ConfigurationErrorsException
{}

BEARBEITEN: Das Schreiben einer eigenen Ausnahme in diesem Fall bietet den zusätzlichen Vorteil, dass garantiert wird, dass keine Verwirrung darüber entsteht, wo die Ausnahme vom Framework oder von Ihrer Anwendung ausgeht. Das Framework wird niemals Ihre benutzerdefinierten Ausnahmen auslösen.

UPDATE: Ich stimme den Kommentaren zu, daher habe ich die Unterklasse in ConfigurationErrorsException from Exception geändert. Ich halte es im Allgemeinen für eine gute Idee, benutzerdefinierte Ausnahmen nach Möglichkeit von vorhandenen Framework-Ausnahmen abzusondern und die Exception-Klasse zu vermeiden, es sei denn, Sie benötigen eine anwendungsspezifische Ausnahme.

31
Dave Swersky

Persönlich würde ich InvalidOperationException verwenden, da dies ein Problem mit dem Objektstatus ist - nicht mit dem Konfigurationssystem. Sollten Sie nicht zulassen, dass diese Einstellungen über den Code und nicht auch über die Konfiguration vorgenommen werden? Der wichtige Teil hier ist nicht, dass es in app.config keine Zeile gab, sondern dass eine erforderliche Information nicht vorhanden war.

Für mich ist ConfigurationException (und sein Ersatz ConfigurationErrorsException - trotz der irreführenden MSDN-Dokumente) für Fehler beim Speichern, Lesen usw. der Konfiguration verantwortlich.

42
Mark Brackett

Wie Daniel Richardson sagte, ist ConfigurationErrorsException die zu verwendende. Im Allgemeinen wird empfohlen, nur dann eigene benutzerdefinierte Ausnahmetypen zu erstellen, wenn Sie ein Szenario haben, in dem diese behandelt werden. Bei Konfigurationsfehlern, die in der Regel schwerwiegende Folgen haben, ist dies selten der Fall. Daher ist es in der Regel sinnvoller, den vorhandenen ConfigurationErrorsException-Typ wiederzuverwenden.

Vor .NET 2.0 wurde empfohlen, System.Configuration.ConfigurationException zu verwenden. Aus Gründen, die mir nie klar waren, wurde ConfigurationException in .NET 2.0 hinfällig, und die Empfehlung für die Verwendung von ConfigurationErrorsException wurde geändert.

Ich verwende eine Hilfsmethode, um die Ausnahme auszulösen, sodass es einfach ist, die Ausnahme zu ändern, die bei der Migration von .NET 1.x auf 2.0 an einer Stelle ausgelöst wird, oder wenn Microsoft beschließt, die Empfehlung erneut zu ändern:

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
        )
        );
}
17
Joe
15
Laurent

ConfigurationErrorsException ist die richtige Ausnahme für die von Ihnen beschriebene Situation. Eine frühere Version der MSDN-Dokumentation für ConfigurationErrorsException ist sinnvoller.

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

Die frühere MSDN-Zusammenfassung und die Anmerkungen lauten:

  • Die Ausnahme, die ausgelöst wird, wenn ein Konfigurationssystemfehler aufgetreten ist.
  • Die Ausnahme ConfigurationErrorsException wird ausgelöst, wenn beim Lesen oder Schreiben von Konfigurationsinformationen ein Fehler auftritt.
8

Die ConfigurationElement-Klasse (die Basisklasse vieler konfigurationsbezogener Klassen wie ConfigurationSection) verfügt über eine Methode namens OnRequiredPropertyNotFound (es gibt auch andere Hilfsmethoden). Sie können diese vielleicht anrufen.

Das OnRequiredPropertyNotFound wird folgendermaßen implementiert:

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)); }
6
Gaspar Nagy

Ich würde es aufsaugen und mein eigenes rollen ... aber bevor Sie das tun, ist es möglich, dass das System einen Standardwert für diese Konfigurationseinstellung annimmt? Ich versuche das im Allgemeinen für jede Einstellung, die von Mitarbeitern des Operations Managements übersehen wird ... (oder vielleicht sollte ich sagen, für so viele Einstellungen wie möglich - für einige ist es eindeutig nicht angebracht, dass das System eine Standardentscheidung trifft. ..)

im Allgemeinen ist eine benutzerdefinierte Ausnahme kein großer Aufwand. Hier ist ein Beispiel.

[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
}
1
Charles Bretana

Eine alternative Methode, die Sie für Ihre Konfigurationsdateien verwenden könnten, wäre die Verwendung benutzerdefinierter Konfigurationsabschnitte im Gegensatz zu AppSettings. Auf diese Weise können Sie festlegen, dass eine Eigenschaft IsRequired und das Konfigurationssystem diese Überprüfung für Sie übernehmen. Wenn die Eigenschaft fehlt, wirft sie ein ConfigurationErrorsException. Ich nehme also an, dass dies die Antwort unterstützt, dass Sie diese Ausnahme in Ihrem Fall verwenden sollten.

1
Yogh

Meine allgemeine Regel wäre:

  1. Wenn der Fall der fehlenden Konfiguration nicht alltäglich ist und ich glaube, dass ich diesen Fall niemals anders als andere Ausnahmen behandeln möchte, verwende ich einfach die grundlegende Klasse "Exception" mit einer entsprechenden Meldung:

    neue Ausnahme auslösen ("meine Nachricht hier")

  2. Wenn ich möchte oder denke, dass es eine hohe Wahrscheinlichkeit gibt, dass ich diesen Fall anders als die meisten anderen Ausnahmen behandeln möchte, würde ich meinen eigenen Typ würfeln, wie die Leute hier bereits vorgeschlagen haben.

0
Hershi

Ich stimme der Prämisse Ihrer Frage nicht zu:

Kurz gesagt, ich benötige eine Standardausnahme, die ausgelöst werden sollte, wenn eine Anwendungskonfigurationseinstellung fehlt oder einen ungültigen Wert enthält. Man könnte meinen, das Framework enthält eine solche Ausnahme, die von Anwendungen verwendet werden kann. (Anscheinend hat es funktioniert, aber es wurde als veraltet markiert und durch etwas viel Größeres ersetzt.)

Laut der MSDN-Dokumentation zu System.Exception ( Exception Class sollten Sie aus Leistungsgründen (auf die andere bei Stack Overflow und an anderer Stelle hingewiesen haben) wirklich keine Ausnahmen für Benutzereingabefehler auslösen. Dies scheint auch sinnvoll zu sein - warum kann Ihre Funktion nicht false zurückgeben, wenn die Benutzereingabe falsch eingegeben wurde und die Anwendung dann ordnungsgemäß beendet wird? Dies scheint eher ein Konstruktionsproblem als ein Problem zu sein, bei dem eine Ausnahme zu werfen ist .

Wie andere darauf hingewiesen haben, gibt es keinen Grund, warum Sie Ihre nicht definieren können, wenn Sie wirklich eine Ausnahme auslösen müssen Ausnahmetyp durch Erben von System.Exception.

0
Matt Jordan