.NET Yapılandırması (app.config / web.config / settings.settings)


162

Hata ayıklama ve sürüm yapıları için farklı yapılandırma dosyaları olan bir .NET uygulaması var. Hata ayıklama app.config dosyası , hata ayıklamanın etkin olduğu bir geliştirme SQL Server'ı ve yayın hedefinin canlı SQL Server'ı işaret ettiğini gösterir. Bazı hata ayıklama / bırakma işlemlerinde farklı olan başka ayarlar da vardır.

Şu anda iki ayrı yapılandırma dosyası kullanıyorum (debug.app.config ve release.app.config). Bu bir sürüm derleme sonra app.config kopyalamak app.config, başka debug.app.config app.config kopyalayın diyor bir derleme olay var.

Sorun, uygulamanın ayarlarını settings.settings dosyasından alıyor gibi görünüyor, bu yüzden ayarları değiştirmeliyim, ayarları değiştirdiğini, böylece ayarları kabul ettiğim, ayarları kaydettiğim ve doğru ayarları kullanmak için yeniden oluşturmak için.

Benzer bir etki elde etmek için daha iyi / önerilen / tercih edilen bir yöntem var mı? Ya da eşit olarak, buna tamamen yanlış yaklaştım ve daha iyi bir yaklaşım var mı?


Ben pencerelerde hata ayıklama devre dışı bırakmak istiyorum, hata ayıklama ayarları tüm onay kutusunun işaretini kaldırarak denedim, ama yine de bin sürümü exe hata ayıklama .. Herkes bana bu konuda .. ..
Vinoth Narayan

Yanıtlar:


62

Ortamlar arasında farklılık gösterebilecek tüm yapılandırmalar , uygulama düzeyinde değil, makine düzeyinde saklanmalıdır . (Yapılandırma düzeyleri hakkında daha fazla bilgi.)

Bunlar, genellikle makine düzeyinde sakladığım yapılandırma öğeleri türüdür:

Her ortamın (geliştirici, entegrasyon, test, sahne alanı, canlı) c: \ Windows \ Microsoft.NET \ Framework64 \ v2.0.50727 \ CONFIG dizininde kendi benzersiz ayarları olduğunda , uygulama kodunuzu tanıtabilirsiniz herhangi bir ortam olmadan ortamlar arasında derleme sonrası değişiklikler.

Açıkçası, makine düzeyinde CONFIG dizininin içeriği, uygulamanızdan farklı bir depoda veya farklı bir klasör yapısında sürüm kontrollü hale gelir. ConfigSource'un akıllı kullanımı sayesinde .config dosyalarınızı daha fazla kaynak denetimi dostu yapabilirsiniz .

Bunu 7 yıldır 25'ten fazla farklı şirkette 200'den fazla ASP.NET uygulamasında yapıyorum. (Övünmeye çalışmıyorum, sadece bu yaklaşımın işe yaramadığı bir durum görmediğimi bildirmek istiyorum .)


3
Web sunucusunu denetlemediğiniz ve bu nedenle makine düzeyinde yapılandırmayı değiştiremediğiniz bir duruma ne dersiniz? Örnek olarak, bir üçüncü taraf web sunucusu veya bir kuruluştaki birden çok departman arasında paylaşılan bir web sunucusu verilebilir.
RationalGeek

1
Çalışmaz. Ancak sanal makineler, Amazon EC2 ve Dell'in 400 dolarlık sunucuları döneminde, paylaşılan makinelerde gerçekten ciddi bir şey yapan var mı? Hiç duygusuz olmaya çalışmıyorum - gerçekten paylaşılan bir web sunucusunda çalışıyorsanız yeniden değerlendirmeniz gerektiğini düşünüyorum.
Portman

7
Dahili sitelerle çalıştığım çoğu şirket, bir sunucuda birden fazla uygulama barındırıyor - kurumsal düzeyde yeniden değerlendirme yapılması gerekiyor
MPritchard

Bir sunucudaki birden çok uygulama, uygulamaların tümü aynı "ortamda" olduğu sürece iyidir. Yani, App1'in LIVE örneğinin, App2'nin DEV örneğiyle aynı sunucuda olmasını istemezsiniz. Örneğin, SMTP ayarlarınız tüm uygulamalarınızda paylaşılır. Üretimde, gerçek bir posta sunucusuna işaret ediyorsunuz; geliştirme sırasında, diskteki bir dosyayı işaret edersiniz.
Portman

7
Bunun işe yarayacağını biliyorum, ancak bu, konuşlandırmayı otomatikleştirmeye çalışırken önerdiğim şeye aykırı. Ayarların uygulamaya özel olduğunu, uygulama ile birlikte sürüm kontrollü olması ve birlikte gelişmesi gerektiğini düşünüyorum. Makine konfigürasyonuna güvenmek sadece değişiyor, bence bir zorlaştırıyor. Değişen şeyleri bir arada tutmayı ve birlikte dağıtmayı seviyorum. Dev için yeni bir ayar eklersem muhtemelen prod için eşdeğer bir ayara ihtiyacım var.
Miguel Madero

52

Bu, bazılarının Ayarlar.settings ve App.config ile uğraşmasına yardımcı olabilir: Visual Studio'da (benim durumumda Visual Studio 2008) herhangi bir değeri düzenlerken Özellikler bölmesinde GenerateDefaultValueInCode özniteliğine dikkat edin.

GenerateDefaultValueInCode öğesini True olarak ayarlarsanız (True, burada varsayılan değerdir!), Varsayılan değer EXE (veya DLL) içinde derlenir, dosyayı düz metin düzenleyicisinde açtığınızda gömülü olarak bulabilirsiniz.

Bir konsol uygulaması üzerinde çalışıyordum ve EXE'de varsayılan olarak ayarlamış olsaydım, uygulama her zaman aynı dizine yerleştirilen yapılandırma dosyasını görmezden geldi! Oldukça bir kabus ve tüm internette bu konuda hiçbir bilgi.


7
Geçtiğimiz hafta sonu boyunca tam da başıma gelen buydu. Uygulamamın app.config dosyamı neden görmezden geldiğini anlamaya çalışırken çok fazla saç çıkardım! Bir web hizmetine bağlanması gerekiyor ve hizmet url'si benim app.config dosyamda. Bilmeden, web referansını oluşturduğumda, aynı zamanda bir Settings.Settings dosyası oluşturdu ve varsayılan değeri koda kodladı. Sonunda ayarlar dosyasını çözdüğümde (ve kaldırdığımda), bu varsayılan değer sabit kodda kaldı ve exe'ye gömüldü. ÇOK KIRMA !! Bu yazı sayesinde, şimdi bu "özellik" kurtulmak
Mike K

+1 Bu cevap kritiktir : Ayarınızın app.config dosyasına girmesini istiyorsanız, GenerateDefaultValueInCode özniteliğini False olarak ayarlayın (varsayılan değer True'dur).
Sabuncu

34

Burada ilgili bir soru var:

Derleme Sürecinizi İyileştirme

Yapılandırma dosyaları ayarları geçersiz kılmak için bir yolla gelir:

<appSettings file="Local.config">

İki dosyayı (veya daha fazlasını) kontrol etmek yerine, yalnızca varsayılan yapılandırma dosyasını kontrol edersiniz ve ardından her hedef makineye, yalnızca belirli bir makine için geçersiz kılmalara sahip olan appSettings bölümü ile birlikte bir Local.config koyarsınız.

Yapılandırma bölümleri kullanıyorsanız, eşdeğer:

configSource="Local.config"

Tabii ki, diğer makinelerden tüm Local.config dosyalarının yedek kopyalarını oluşturmak ve bir yerde kontrol etmek iyi bir fikirdir, ancak gerçek çözümlerin bir parçası olarak değil. Her geliştirici, başkalarının dosyalarının üzerine yazacak şekilde teslim edilmemesi için Local.config dosyasına bir "yoksay" koyar.

(Aslında buna "Local.config" adını vermek zorunda değilsiniz, sadece bunu kullanıyorum)


14

Okuduğum kadarıyla, oluşturma işleminiz için Visual Studio kullandığınız anlaşılıyor. MSBuild ve Nant kullanmayı düşündünüz mü?Bunun yerine ?

Nant'ın xml sözdizimi biraz garip ama anladıktan sonra, bahsettiğiniz şeyi yapmak oldukça önemsiz hale geliyor.

<target name="build">
    <property name="config.type" value="Release" />

    <msbuild project="${filename}" target="Build" verbose="true" failonerror="true">
        <property name="Configuration" value="${config.type}" />
    </msbuild>

    <if test="${config.type == 'Debug'}">
        <copy file=${debug.app.config}" tofile="${app.config}" />
    </if>

    <if test="${config.type == 'Release'}">
        <copy file=${release.app.config}" tofile="${app.config}" />
    </if>

</target>


8

Eskiden Web Dağıtımı projeleri kullanıyorduk ama o zamandan beri NAnt'a geçtik. Farklı ayar dosyalarını dallandırmak ve kopyalamak yerine, şu anda yapılandırma değerlerini doğrudan oluşturma komut dosyasına gömüyoruz ve xmlpoke görevleri aracılığıyla yapılandırma dosyalarımıza enjekte ediyoruz:

  <xmlpoke
    file="${stagingTarget}/web.config"
    xpath="/configuration/system.web/compilation/@debug"
    value="true"
  />

Her iki durumda da, yapılandırma dosyalarınız istediğiniz geliştirici değerlerine sahip olabilir ve üretim sistemlerinizi bozmadan geliştirici ortamınızdan iyi çalışır. Geliştiricilerin işleri test ederken derleme komut dosyası değişkenlerini keyfi olarak değiştirme olasılığının daha düşük olduğunu tespit ettik. dev değeri varsayılan olarak prod değerine aktarılmaz.


7

Mevcut işverenim bu sorunu öncelikle machine.config dosyasına geliştirici düzeyini (hata ayıklama, sahne, canlı vb.) Koyarak çözdü. Sonra bunu almak ve doğru yapılandırma dosyasını kullanmak için kod yazdılar. Bu, uygulama dağıtıldıktan sonra yanlış bağlantı dizesiyle ilgili sorunu çözdü.

Kısa bir süre önce, machine.config değerindeki değerden doğru bağlantı dizesini geri gönderen merkezi bir web hizmeti yazdılar.

Bu en iyi çözüm mü? Muhtemelen hayır, ama onlar için çalışıyor.


1
Aslında bence bu çok zarif, çünkü canlı olmasalar bile, çeşitli yapılandırma sürümlerini bir çözüm içinde görünür tutmaktan hoşlanıyorum.
annakata

1
Bu çok ilgi çekici bir çözüm. Eylemde bunun bir örneğini gözden geçirmek isterim.
Mike K

5

Bana iyi gelen çözümlerden biri bir WebDeploymentProject kullanmaktı. Sitemde 2/3 farklı web.config dosyası vardı ve seçilen yapılandırma moduna (yayınlama / evreleme / vb.) Bağlı olarak yayınladım. Web.Release.config üzerinden kopyalayıp web olarak yeniden adlandırırım. AfterBuild olayında yapılandırın ve ihtiyacım olanları silin (örneğin Web.Staging.config).

<Target Name="AfterBuild">
    <!--Web.config -->
    <Copy Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " SourceFiles="$(SourceWebPhysicalPath)\Web.Release.config" DestinationFiles="$(OutputPath)\Web.config" />
    <Copy Condition=" '$(Configuration)|$(Platform)' == 'Staging|AnyCPU' " SourceFiles="$(SourceWebPhysicalPath)\Web.Staging.config" DestinationFiles="$(OutputPath)\Web.config" />
    <!--Delete extra files -->
    <Delete Files="$(OutputPath)\Web.Release.config" />
    <Delete Files="$(OutputPath)\Web.Staging.config" />
    <Delete Files="@(ProjFiles)" />
  </Target>


3

Projemiz, dev, qa, uat ve prod için yapılandırmaları korumak zorunda kaldığımız aynı sorunu yaşıyor. İşte takip ettiklerimiz (yalnızca MSBuild hakkında bilginiz varsa geçerlidir):

MSBuild MSBuild Topluluğu görev uzantısıyla kullanın. Başlamak için doğru düğümü verdiğinizde, herhangi bir XML dosyasındaki girdileri 'toplu olarak güncelleyebilen' 'XmlMassUpdate' görevini içerir.

Uygulamaya:

1) dev env girişlerinizi içeren bir yapılandırma dosyasına sahip olmanız gerekir; bu, çözümünüzdeki yapılandırma dosyasıdır.

2) Her ortam için yalnızca FARKLI (çoğunlukla appSettings ve ConnectionStrings) girişleri içeren bir 'Substitutions.xml' dosyanız olması gerekir. Ortamda değişmeyen girdilerin bu dosyaya konması gerekmez. Çözümün web.config dosyasında yaşayabilirler ve görev tarafından dokunulmazlar

3) Derleme dosyanızda, XML toplu güncelleme görevini çağırın ve parametre olarak doğru ortamı sağlayın.

Aşağıdaki örneğe bakın:

    <!-- Actual Config File -->
    <appSettings>
        <add key="ApplicationName" value="NameInDev"/>
        <add key="ThisDoesNotChange" value="Do not put in substitution file" />
    </appSettings>

    <!-- Substitutions.xml -->
    <configuration xmlns:xmu="urn:msbuildcommunitytasks-xmlmassupdate">
      <substitutions>
        <QA>
           <appSettings>
            <add xmu:key="key" key="ApplicationName" value="NameInQA"/>
           </appSettings>            
        </QA>
        <Prod>
          <appSettings>
            <add xmu:key="key" key="ApplicationName" value="NameInProd"/>
          </appSettings>            
        </Prod>
     </substitutions>
    </configuration>


<!-- Build.xml file-->

    <Target Name="UpdateConfigSections">
            <XmlMassUpdate ContentFile="Path\of\copy\of\latest web.config" SubstitutionsFile="path\of\substitutionFile" ContentRoot="/configuration" SubstitutionsRoot="/configuration/substitutions/$(Environment)" />
        </Target>

'$ Environment' ortamını 'QA' veya 'Prod' ile değiştirin. için inşa ediyorsun. Kurtarılamayan olası hatalardan kaçınmak için gerçek yapılandırma dosyasının değil, bir yapılandırma dosyasının kopyası üzerinde çalışmanız gerektiğini unutmayın.

Sadece derleme dosyasını çalıştırın ve güncelleştirilmiş yapılandırma dosyasını dağıtım ortamınıza taşıyın ve işiniz bitti!

Daha iyi bir genel bakış için şunu okuyun:

http://blogs.microsoft.co.il/blogs/dorony/archive/2008/01/18/easy-configuration-deployment-with-msbuild-and-the-xmlmassupdate-task.aspx


2

Senin gibi Ben de 'multi' app.config kurdum - örneğin app.configDEV, app.configTEST, app.config.LOCAL. Önerilen mükemmel alternatiflerden bazılarını görüyorum, ancak sizin için çalışma şeklini beğenirseniz, aşağıdakileri eklerdim:

Ben
<appSettings>
<add key = "Env" value = "[Local] "/> her uygulama için bunu başlık çubuğundaki kullanıcı arayüzüne ekliyorum: from ConfigurationManager.AppSettings.Get ("Env");

Ben sadece yapılandırmayı hedeflediğim olarak yeniden adlandırıyorum (4 uygulamalara karşı çok sayıda veritabanı / wcf yapılandırma içeren 8 uygulamalı bir projem var). Clickonce ile her birine dağıtmak için projedeki 4 sekansı değiştirip gidiyorum. (bunu otomatikleştirmek isterim)

Tek ayarlamam, bir değişiklikten sonra 'tümünü temizlemeyi' hatırlamaktır, çünkü eski yapılandırma manuel olarak yeniden adlandırıldıktan sonra 'sıkışmış'. (Sanırım size setting.setting sorununu düzeltir).

Bunun gerçekten işe yaradığını görüyorum (bir gün MSBuild / NAnt'a bakmak için zaman alacağım)


0

Web.config:

Uygulamanızı IIS'de barındırmak istediğinizde Web.config gereklidir. Web.config, IIS'nin Kestrel'in önünde nasıl ters proxy olarak davranacağını yapılandırması için zorunlu bir yapılandırma dosyasıdır. IIS'de barındırmak istiyorsanız bir web.config dosyasını korumanız gerekir.

AppSetting.json:

IIS ile ilgili olmayan her şey için AppSetting.json komutunu kullanırsınız. AppSetting.json, Asp.Net Core hosting için kullanılır. ASP.NET Core geçerli ortamı belirlemek için "ASPNETCORE_ENVIRONMENT" ortam değişkenini kullanır. Varsayılan olarak, uygulamanızı bu değeri ayarlamadan çalıştırırsanız, otomatik olarak Üretim ortamını varsayılan olarak kullanır ve "AppSetting.production.json" dosyasını kullanır. Visual Studio ile hata ayıkladığınızda, ortam "AppSetting.json" kullanır, bu nedenle geliştirme ayarlar. Windows'ta barındırma ortamı değişkeninin nasıl ayarlanacağını anlamak için bu web sitesine bakın.

app.config:

App.config, .NET tarafından kullanılan ve çoğunlukla Windows Forms, Windows Hizmetleri, Konsol Uygulamaları ve WPF uygulamaları için kullanılan başka bir yapılandırma dosyasıdır. Asp.Net Core sunucunuzu konsol uygulaması üzerinden başlattığınızda app.config de kullanılır.


TL; DR

Yapılandırma dosyasının seçimi, hizmet için seçtiğiniz barındırma ortamı tarafından belirlenir. Hizmetinizi barındırmak için IIS kullanıyorsanız, bir Web.config dosyası kullanın. Başka bir barındırma ortamı kullanıyorsanız bir App.config dosyası kullanın. Bkz Yapılandırma Dosyaları belgelerini kullanma Yapılandırma Hizmetleri check out ayrıca ve ASP.NET Core Yapılandırma.


0

Yukarıdaki asp.net diyor, neden ayarlarınızı veritabanına kaydetmiyorsunuz ve almak için özel bir önbellek kullanmıyorsunuz?

Bunu yapmamızın sebebi, sürekli veritabanını güncellemenin (bizim için) üretim dosyalarını sürekli güncellemek için izin almaktan daha kolaydır.

Özel Önbellek Örneği:

public enum ConfigurationSection
{
    AppSettings
}

public static class Utility
{
    #region "Common.Configuration.Configurations"

    private static Cache cache = System.Web.HttpRuntime.Cache;

    public static String GetAppSetting(String key)
    {
        return GetConfigurationValue(ConfigurationSection.AppSettings, key);
    }

    public static String GetConfigurationValue(ConfigurationSection section, String key)
    {
        Configurations config = null;

        if (!cache.TryGetItemFromCache<Configurations>(out config))
        {
            config = new Configurations();
            config.List(SNCLavalin.US.Common.Enumerations.ConfigurationSection.AppSettings);
            cache.AddToCache<Configurations>(config, DateTime.Now.AddMinutes(15));
        }

        var result = (from record in config
                      where record.Key == key
                      select record).FirstOrDefault();

        return (result == null) ? null : result.Value;
    }

    #endregion
}

namespace Common.Configuration
{
    public class Configurations : List<Configuration>
    {
        #region CONSTRUCTORS

        public Configurations() : base()
        {
            initialize();
        }
        public Configurations(int capacity) : base(capacity)
        {
            initialize();
        }
        public Configurations(IEnumerable<Configuration> collection) : base(collection)
        {
            initialize();
        }

        #endregion

        #region PROPERTIES & FIELDS

        private Crud _crud; // Db-Access layer

        #endregion

        #region EVENTS
        #endregion

        #region METHODS

        private void initialize()
        {
            _crud = new Crud(Utility.ConnectionName);
        }

        /// <summary>
        /// Lists one-to-many records.
        /// </summary>
        public Configurations List(ConfigurationSection section)
        {
            using (DbCommand dbCommand = _crud.Db.GetStoredProcCommand("spa_LIST_MyConfiguration"))
            {
                _crud.Db.AddInParameter(dbCommand, "@Section", DbType.String, section.ToString());

                _crud.List(dbCommand, PopulateFrom);
            }

            return this;
        }

        public void PopulateFrom(DataTable table)
        {
            this.Clear();

            foreach (DataRow row in table.Rows)
            {
                Configuration instance = new Configuration();
                instance.PopulateFrom(row);
                this.Add(instance);
            }
        }

        #endregion
    }

    public class Configuration
    {
        #region CONSTRUCTORS

        public Configuration()
        {
            initialize();
        }

        #endregion

        #region PROPERTIES & FIELDS

        private Crud _crud;

        public string Section { get; set; }
        public string Key { get; set; }
        public string Value { get; set; }

        #endregion

        #region EVENTS
        #endregion

        #region METHODS

        private void initialize()
        {
            _crud = new Crud(Utility.ConnectionName);
            Clear();
        }

        public void Clear()
        {
            this.Section = "";
            this.Key = "";
            this.Value = "";
        }
        public void PopulateFrom(DataRow row)
        {
            Clear();

            this.Section = row["Section"].ToString();
            this.Key = row["Key"].ToString();
            this.Value = row["Value"].ToString();
        }

        #endregion
    }
}
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.