.NET: Gerekli Yapılandırma Ayarı Eksik Olduğunda Hangi İstisna Atılır?


123

İşte standart bir senaryo:

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

Sorun şu ki, hangi istisnanın SomeStandardExceptionolması gerektiğinden tam olarak emin değilim .

3.5 Çerçevesini inceledim ve iki olası aday buldum: ConfigurationExceptionve ConfigurationErrorsException.

System.Configuration.ConfigurationException

Bir konfigürasyon sistem hatası oluştuğunda ortaya çıkan istisna.

Uyarılar

ConfigurationExceptionUygulama girişimleri okumak veya yapılandırma dosyasına yazma veri ancak başarısız olduğunu eğer durum atılır. Bunun bazı olası nedenleri, yapılandırma dosyasında hatalı biçimlendirilmiş XML, dosya izni sorunları ve geçerli olmayan değerlere sahip yapılandırma özelliklerini içerebilir.

Not:

ConfigurationExceptionNesne geriye doğru uyumluluk için muhafaza edilmektedir. ConfigurationErrorsException Nesne yapılandırması sistemi için değiştirir.

Bu istisna, aslında ihtiyacım olan şey için mükemmel görünüyor, ancak modası geçmiş olarak işaretlendi, bu yüzden, ixnay on atthay.

Bu bizi tamamen kafa karıştırıcı hale getiriyor ConfigurationErrorsException:

System.Configuration.ConfigurationErrorsException

Geçerli değer, EnableSessionState değerlerinden biri değil.

Gördüğünüz gibi, dokümantasyonu tamamen işe yaramaz. (Hem yerel hem de çevrimiçi yardımda bu şekilde.) Sınıfın kendisinin incelenmesi, istediğim şey için aşırı derecede abartılı olduğunu gösteriyor.

Özetle, bir uygulama yapılandırma ayarı eksik olduğunda veya geçersiz bir değer içerdiğinde atılması gereken standart bir istisnaya ihtiyacım var. Uygulamaların kullanması için Framework'ün böyle bir istisnası olduğunu düşünürdünüz. (Görünüşe göre yaptı, ancak eski olarak işaretlendi ve kapsamı çok daha büyük bir şeyle değiştirildi .)

Eğer varsa, bunun için hangi çözümleri kullanıyorsunuz ve bunun için kendi istisnamı almam gerekecek mi?

Addenda'yı düzenleyin

Bazıları varsayılan bir değer sağlayıp sağlayamayacağımı sordu ve devam etti. Bazı durumlarda evet ve bu durumlarda istisna atılmayacaktır. Ancak belirli ayarlar için bu geçerli olmayacaktır. Örneğin: veritabanı sunucusu adları ve kimlik bilgileri, kimlik doğrulama sunucuları ve yüklü üçüncü taraf uygulamalarına giden yollar.

Öncelikle üzerinde çalıştığım uygulamanın toplu modda çalışan bir konsol uygulaması olduğunu ve bunun, uygun şekilde yapılandırılmamışsa ana yöntem tarafından yakalanan ve uygun şekilde günlüğe kaydedilen bir istisna atmasını istiyorum. (Miras aldığım eski kod ve şu anda her şeyin şeftali gibi olduğunu varsayıyor .)


1
İçin dokümantasyon System.Configuration.ConfigurationErrorsException güncellendi.
slolife

Yanıtlar:


36

Çerçevede mevcut istisnalar ile istisna atma konusunda sınırlı değilsiniz. Mevcut istisnaları kullanmaya karar verirseniz, belgelere harfiyen uymanız gerekmez. Nasıl dokümantasyon anlatacağız çerçeve verilen bir istisna kullanır, ama nasıl herhangi bir kısıtlama anlamına gelmez Eğer mevcut bir istisna yeniden kullanım / kullanımına seçin.

Bu sizin uygulamanızdır - bunu belgelediğiniz ve eksik bir yapılandırma değeri durumunda ortaya çıkacak istisnayı açıkça belirttiğiniz sürece, istediğiniz herhangi bir istisnayı kullanabilirsiniz. Eksik bir değerin çok spesifik bir gösterimini istiyorsanız, kendi ConfigurationSettingMissing istisnanızı yazmayı düşünebilirsiniz:

[Serializable]
public class ConfigurationMissingException : ConfigurationErrorsException
{}

DÜZENLEME: Bu durumda kendi istisnanızı yazmak, istisnanın çerçeveden veya uygulamanızdan nereden geldiğine dair hiçbir kafa karışıklığı olmayacağını garanti etmenin ek faydasını taşır. Çerçeve asla özel istisnalarınızı atmaz.

GÜNCELLEME: Yorumlara katılıyorum, bu nedenle alt sınıfı Exception'dan ConfigurationErrorsException olarak değiştirdim. Uygulamaya özel bir istisnaya ihtiyacınız olmadıkça Exception sınıfından kaçınarak, mümkün olduğunda özel istisnaları mevcut Framework istisnalarından alt sınıflara ayırmanın genellikle iyi bir fikir olduğunu düşünüyorum.


17
Ben pek katılmıyorum. Mevcut bir istisnayı kullanacaksanız, tam olarak belgelerde söylendiği gibi kullanılmalıdır, yoksa sizden sonra gelenlerin kafasını karıştırırsınız. Farklı bir şey yapacaksanız, söylediğiniz gibi kendi istisnanızı yaratın.
Robert C. Barth

1
Katılmıyorum. Özel istisnanızı yakalamak için bir senaryonuz yoksa, olasılıkla bir konfigürasyon hatası durumunda, mevcut bir Tipi (ConfigurationErrorsException) yeniden kullanmak daha iyidir. Ve özel bir Tür oluşturursanız, bunu ConfigurationErrorsException gibi ilgili bir Türden elde ederim.
Joe

@Robert & Joe- Mevcut Çerçeve istisnalarının amaçlanan işlevleriyle tutarsız bir şekilde kullanılması gerektiğini önermiyorum, sadece belirli durum (eksik değer) genel durumla (ConfigurationErrorsException) uyumlu olduğu sürece biraz esneklik var.
Dave Swersky

1
Bir ASP.NET uygulamasında özel durumu ConfigurationErrorsException olarak atıyorsanız ve ondan türetilen sınıflar korumalı OnError yöntemine veya Global ASAX Error olayına yakalanmıyorsa, bununla ilgili sorunlar olabilir. Gönderdiğim bu soruya bakın .... stackoverflow.com/questions/25299325/…
Mick

48

Kişisel olarak, InvalidOperationException'ı kullanırdım , çünkü bu, konfigürasyon sistemiyle değil, nesne durumuyla ilgili bir sorun. Sonuçta, bu ayarların kodla yapılmasına ve yapılandırılmasına izin vermemeli misiniz? Buradaki önemli kısım, app.config dosyasında satır olmaması değil, gerekli bir bilginin mevcut olmamasıdır.

Bana göre, ConfigurationException (ve onun yerine, ConfigurationErrorsException - yanıltıcı MSDN belgelerine rağmen) Yapılandırmanın kaydedilmesi, okunması vb. Hatalar içindir.


ASP.NET Page korumalı OnError yöntemi tarafından işlendiği için InvalidOperationException'ı seçtim, ConfigurationErrorsException ve ondan türetilen tüm istisnalar değil
Mick

2
Yapılandırmayı yanlış yaparsam bir InvalidOperationException alırsam bu beni gerçekten şaşırtabilir.
keuleJ

18

Daniel Richardson'ın dediği gibi, ConfigurationErrorsException kullanılacak olanıdır. Genel olarak, yalnızca kendi özel İstisna türlerinizi, bunları işleyecek bir senaryonuz varsa oluşturmanız önerilir. Genellikle ölümcül olan yapılandırma hataları durumunda, bu nadiren görülür, bu nedenle genellikle mevcut ConfigurationErrorsException türünü yeniden kullanmak daha uygundur.

.NET 2.0'dan önce, öneri System.Configuration.ConfigurationException'ı kullanmaktı . ConfigurationException benim için hiçbir zaman anlaşılmayan nedenlerden dolayı .NET 2.0'da geçersiz hale geldi ve öneri ConfigurationErrorsException'ı kullanmak için değiştirildi.

.NET 1.x'ten 2.0'a geçerken veya Microsoft öneriyi yeniden değiştirmeye karar verirse, istisnayı atmak için yardımcı bir yöntem kullanıyorum:

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
        )
        );
}


7

ConfigurationErrorsExceptiontarif ettiğiniz durumda atılacak doğru istisnadır. MSDN belgelerinin daha önceki bir sürümü ConfigurationErrorsExceptiondaha mantıklı.

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

Önceki MSDN özeti ve açıklamalar şunlardır:

  • Bir yapılandırma sistemi hatası oluştuğunda ortaya çıkan istisna.
  • ConfigurationErrorsException İstisna yapılandırma bilgileri okumak veya yazılırken herhangi bir hata oluştuğunda atılır.

7
belgelerden: "Bu API, ürün altyapısını destekler ve doğrudan kodunuzdan kullanılması amaçlanmamıştır. ConfigurationErrorsException sınıfının yeni bir örneğini başlatır."
Oleg Sh

6

ConfigurationElement sınıfı (ConfigurationSection gibi birçok yapılandırma ile ilgili sınıfın temel sınıfıdır) OnRequiredPropertyNotFound adında bir yönteme sahiptir (başka yardımcı yöntemler de vardır). Belki onları arayabilirsin.

OnRequiredPropertyNotFound şu şekilde uygulanır:

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)); }

1

Bunu emer ve kendim yuvarlardım ... ama bunu yapmadan önce, sistemin bu yapılandırma ayarı için varsayılan bir değer alması mümkün mü? Genelde bunu, Ops Management halkında gözden kaçabilecek her ayar için yapmaya çalışıyorum ... (veya belki mümkün olduğunca çok ayar için söylemeliyim - bazıları için sistemin varsayılan bir karar vermesi açıkça uygun değildir. ..)

genel olarak özel bir istisna çok çaba gerektirmez ... işte bir örnek ...

[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
}

2
MSDN: ... kendi istisnalarını yaratması gereken bir uygulama, [...] Exception sınıfından özel istisnalar türetmesi. Başlangıçta, özel istisnaların ApplicationException sınıfından türetilmesi gerektiği düşünülüyordu; ancak pratikte bunun önemli bir değer kattığı görülmemiştir.
Gaspar Nagy

Evet, sanırım çerçeveyi kodlayan MS programcıları ApplicationException'dan çok sayıda CLR istisnası
çıkardılar

1

Yapılandırma dosyalarınız için kullanabileceğiniz alternatif bir yöntem, yerine özel yapılandırma bölümleri kullanmaktır AppSettings. Bu şekilde, bir özelliğin IsRequiredve konfigürasyon sisteminin bu kontrolü sizin için halledeceğini belirtebilirsiniz . Özellik eksikse ConfigurationErrorsException, sizin durumunuzda bu istisnayı kullanmanız gerektiğine dair yanıtı desteklediğini tahmin ediyorum.


0

Genel kuralım:

  1. Eksik yapılandırma durumu çok yaygın değilse ve bu vakayı diğer istisnalardan farklı şekilde ele almak istemeyeceğime inanıyorsam, yalnızca temel "İstisna" sınıfını uygun bir mesajla kullanırım:

    yeni İstisna oluştur ("mesajım buraya")

  2. İstersem veya bu vakayı diğer istisnaların çoğundan farklı bir şekilde ele almak isterdim, ya da yüksek bir olasılık olduğunu düşünürsem, insanların burada zaten önerdiği gibi kendi tipimi atardım.


0

Sorunuzun öncülüne katılmıyorum:

Özetle, bir uygulama yapılandırma ayarı eksik olduğunda veya geçersiz bir değer içerdiğinde atılması gereken standart bir istisnaya ihtiyacım var. Uygulamaların kullanması için Framework'ün böyle bir istisnası olduğunu düşünürdünüz. (Görünüşe göre yaptı, ancak eski olarak işaretlendi ve kapsamı çok daha büyük bir şeyle değiştirildi.)

System.Exception ( İstisna Sınıfı) üzerindeki MSDN belgelerine göre , performans nedenleriyle (Stack Overflow ve başka yerlerde başkaları tarafından işaret edilen) kullanıcı giriş hataları için istisnalar atmamalısınız. peki - kullanıcı girişi yanlış girilirse ve daha sonra uygulamadan zarif bir şekilde çıkılırsa neden işleviniz yanlış döndüremiyor? Bu bir tasarım probleminden çok İstisnanın atılacağı bir sorun gibi görünüyor.

Eğer gerçekten eğer diğerleri, işaret gibi var sebebi ne olursa olsun - - bir istisna size System.Exception devralmasını ederek İstisna türünü tanımlamak olamazdı herhangi bir neden yoktur.


2
Bu özel senaryoda performans tam olarak neden önemli? IUC, o zaman istisna tam olarak bir kez atılır ve işlem muhtemelen daha sonra aşağı iner (tabii ki, kullanıcıya güzel bir açılır pencere gösterdikten sonra). (devam edecek ...)

2
Bir istisna atmak yerine bir hata kodu döndürmek acı verici olabilir, çünkü o zaman hata bilgisini çağrı yığınına kendiniz yaymanız gerekir. Birkaç yığın çerçevesine yayılabilecek nispeten nadir hatalar için özel durumlar kullanmalısınız. Her ikisi de burada geçerlidir.

1
Bir şeyi kaçırdınız: "bir uygulama yapılandırma ayarı eksik olduğunda veya geçersiz bir değer içerdiğinde", bu kötü kullanıcı girdisi ile aynı şey değildir. Bu, eksik olan temel bir yapılandırmadır. Özel bir istisna olmalı ve uygulamanın çalışmasını durdurmalıdır.
jcollum

2
Bu özel uygulamada, neredeyse tamamen konfigürasyon dosyasındaki ayarlar tarafından yönlendirilir. Ayarlar içinde değilse (şifreli oldukları yerde), uygulama devam edemez ve sona erdirilmelidir. Neredeyse bir istisna gereklidir.
Mike Hofer

1
Bu kesinlikle anlam bilime girebilir ve kodunuzun yapısı durumunuz için en iyi uygulamayı açıkça belirleyecektir. Yine de, tasarımda özgür hakimiyetiniz olsaydı, yine de hatayı günlüğe kaydetmek için bir nesne ve bir istisna üzerinde zarif bir çıkış, performans bir sorun olsun ya da olmasın.
Matt Jordan

-2

XML İstisnasını devralmayı veya sadece kullanmayı deneyebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.