Configuration .NET (app.config / web.config / settings.paramètre)

j'ai une application .NET qui a des fichiers de configuration différents pour le débogage et les constructions de publication. E. g. le débogage de l'application.le fichier de configuration pointe vers un développement SQL Server qui a permis le débogage et la cible de publication pointe vers le serveur SQL en direct. Il y a aussi d'autres paramètres, dont certains sont différentes en debug/release.

j'utilise actuellement deux fichiers de configuration distincts (debug.App.config et de la libération.App.config). J'ai un build événement sur le projet qui dit s'il s'agit d'une version construire puis Copier la version.App.config app.config, autre copie debug.App.config app.config.

Le problème est que l'application semble pour obtenir ses paramètres à partir des paramètres.paramètres fichier, donc je dois ouvrir paramètres.paramètres dans Visual Studio qui me demande ensuite que les paramètres ont changé, donc j'accepte les modifications, enregistrer les paramètres.paramètres et à reconstruire pour qu'il utilise les paramètres corrects.

Existe-t-il une méthode meilleure/recommandée/préférée pour obtenir un effet similaire? Ou aussi, je l'ai approché de cette complètement faux et est-il une meilleure approche?

159
demandé sur N30 2008-09-25 14:39:09

13 réponses

toute configuration qui pourrait différer d'un environnement à l'autre doit être stockée au niveau machine , et non au niveau application . (plus d'informations sur les niveaux de configuration.)

ce sont les types d'éléments de configuration que je stocke habituellement au niveau de la machine:

lorsque chaque environnement (développeur, intégration, test, stage, live) a son propres paramètres uniques dans le c:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG répertoire, alors vous pouvez promouvoir votre code d'application entre les environnements sans aucune modification de post-construction.

et évidemment, le contenu du répertoire de configuration au niveau de la machine est contrôlé dans un référentiel différent ou une structure de dossier différente de celle de votre application. Tu peux faire le tien .plus de contrôle des sources utilisation conviviale et intelligente de configSource .

je fais ça depuis 7 ans, sur plus de 200 ASP.NET applications dans plus de 25 entreprises différentes. (Je ne veux pas me vanter, je veux juste que vous sachiez que je n'ai jamais vu une situation où cette approche ne fonctionne pas .)

59
répondu Portman 2012-12-29 01:27:55

cela pourrait aider certaines personnes aux prises avec des situations.les paramètres et l'Application.config: attention à L'attribut GenerateDefaultValueInCode dans le volet Propriétés lors de l'édition des valeurs dans les paramètres.grille des paramètres dans Visual Studio (Visual Studio 2008 dans mon cas).

si vous définissez GenerateDefaultValueInCode à True (True est la valeur par défaut ici!), la valeur par défaut est compilée dans L'EXE( ou DLL), vous pouvez la trouver embarquée dans le fichier lorsque vous l'ouvrez dans un simple éditeur de texte.

je travaillais sur une application console et si j'avais des défauts dans L'EXE, l'application ignorait toujours la place du fichier de configuration dans le même répertoire! Tout un cauchemar et aucune information à ce sujet sur L'ensemble de L'Internet.

50
répondu Roman 2009-12-12 20:02:04

il y a une question connexe ici:

Améliorer Votre Processus De Construction

les fichiers de configuration sont livrés avec un moyen de modifier les paramètres:

<appSettings file="Local.config">

au lieu de vérifier deux fichiers (ou plus), vous ne vérifiez que le fichier de configuration par défaut, puis sur chaque machine cible, vous mettez un Local.config, avec juste la section appSettings qui a les overrides pour cette machine particulière.

si vous utilisez des sections de configuration, l'équivalent est:

configSource="Local.config"

bien sûr, c'est une bonne idée de faire des copies de sauvegarde de tous les locaux.config des fichiers d'autres machines et les vérifier quelque part, mais pas comme une partie des solutions réelles. Chaque développeur met un "ignorer" sur le Local.fichier de configuration pour qu'il ne soit pas enregistré, ce qui écraserait le fichier de tout le monde.

(il n'est pas nécessaire de l'appeler "Local".config", c'est juste ce que j'utilise)

33
répondu Eric Z Beard 2017-05-23 11:46:57

D'après ce que je lis, on dirait que vous utilisez Visual Studio pour votre processus de construction. Avez-vous pensé à utiliser MSBuild et Nant à la place?

la syntaxe xml de Nant est un peu bizarre mais une fois que vous l'avez compris, faire ce que vous avez mentionné devient assez banal.

<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>
14
répondu Steven Williams 2008-09-25 11:12:24

Pour moi, il semble que vous pouvez bénéficier de la Visual Studio 2005 Projet de Déploiement Web .

avec cela, vous pouvez lui dire de mettre à jour/modifier des sections de votre web.fichier de configuration en fonction de la configuration de build.

jetez un oeil à cette entrée de blog de Scott Gu pour un aperçu rapide/échantillon.

11
répondu Magnus Johansson 2008-09-25 10:57:02

nous avions l'habitude d'utiliser des projets de déploiement Web, mais nous avons depuis migré vers NAnt. Au lieu de brancher et de copier différents fichiers de configuration, nous avons incorporé les valeurs de configuration directement dans le script de compilation et nous les injectons dans nos fichiers de configuration via les tâches xmlpoke:

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

dans tous les cas, vos fichiers de configuration peuvent avoir les valeurs de développeur que vous voulez et ils fonctionneront très bien à partir de votre environnement dev sans casser vos systèmes de production. Nous avons nous avons constaté que les développeurs sont moins susceptibles de modifier arbitrairement les variables de script de construction lors des tests, donc les erreurs de configuration accidentelles ont été plus rares qu'avec d'autres techniques que nous avons essayées, bien qu'il soit toujours nécessaire d'ajouter chaque var au début du processus afin que la valeur dev ne soit pas poussée à prod par défaut.

8
répondu jasondoucette 2008-09-25 11:36:25

mon employeur actuel a résolu ce problème en mettant d'abord le niveau dev (debug, stage, live, etc.) dans la machine.fichier de configuration. Puis ils ont écrit le code pour le récupérer et utiliser le bon fichier de configuration. Cela a résolu le problème avec la mauvaise chaîne de connexion après le déploiement de l'application.

ils viennent d'écrire un webservice central qui renvoie la chaîne de connexion correcte de la valeur de la machine.valeur de configuration.

est - ce le meilleur la solution? Probablement pas, mais ça marche pour eux.

7
répondu Hector Sosa Jr 2008-09-25 10:46:20

L'une des solutions qui m'a bien fonctionné était l'utilisation d'un projet de Webdéploiement. J'avais 2/3 web différents.fichiers de configuration sur mon site, et sur publish, en fonction du mode de configuration sélectionné (release/staging/etc...) Je copie sur le Web.Publier.config et renommer en web.config dans la AfterBuild événement, et de supprimer ceux que je n'ai pas besoin (pour le Web.Staging.config par exemple).

<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>
5
répondu Adam Vigh 2008-09-25 11:14:20

vous trouverez une autre solution ici: meilleure façon de passer de la configuration entre les environnements de développement/UAT/Prod en ASP.NET je ne sais pas. qui utilise XSLT pour transférer le web.config.

il y a aussi de bons exemples d'utilisation de NAnt.

3
répondu Aaron Powell 2017-05-23 12:25:52

notre projet a le même problème où nous avons dû maintenir les configs pour dev, qa, uat et prod. Voici ce que nous avons suivi (ne s'applique que si vous êtes familier avec MSBuild):

utilisez MSBuild avec L'extension des tâches de la communauté MSBuild. Il inclut la tâche' XmlMassUpdate 'qui peut' mass-update ' entrées dans n'importe quel fichier XML une fois que vous lui donnez le noeud correct pour commencer.

À Mettre En Œuvre:

1) vous devez avoir un fichier de configuration qui aura vos entrées dev env; c'est le fichier de configuration dans votre solution.

2) vous devez avoir des Substitutions a'.fichier xml', qui contient uniquement les entrées qui sont différentes (appSettings et Connections principalement) pour chaque environnement. Les entrées qui ne changent pas à travers l'environnement n'ont pas besoin d'être mises dans ce fichier. Ils peuvent vivre sur le web.fichier de configuration de la solution et ne sera pas touché par la tâche

3) dans votre fichier de construction, il suffit d'appeler le XML masse tâche de mise à jour et de fournir le droit de l'environnement en tant que paramètre.

Voir exemple ci-dessous:

    <!-- 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>

remplacer "$environnement " par " QA " ou "Prod" sur la base de quoi env. vous êtes à la construction. Notez que vous devez travailler sur une copie d'un fichier de configuration et non sur le fichier de configuration lui-même pour éviter toute erreur non récupérable.

exécutez simplement le fichier de compilation et déplacez ensuite le fichier de configuration mis à jour vers votre déploiement environnement et vous êtes fait!

pour un meilleur aperçu, lisez ceci:

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

3
répondu Punit Vora 2009-06-18 21:42:15

comme vous, j'ai aussi configuré l'application' multi'.config-eg app.configDEV, app.configTEST, app.config.LOCAL. Je vois quelques-unes de l'excellente alternative suggérée, mais si vous aimez la façon dont cela fonctionne pour vous, je voudrais ajouter ce qui suit:

j'ai un

<appSettings>

<add key = "Env" value = "[Local] "/> pour chaque application j'ajoute ceci à L'UI dans la barre de titre: de ConfigurationManager.AppSettings.Get ("Env");

je viens de renommer la config en celui que je cible (j'ai un projet avec 8 applications avec beaucoup de config de base de données/wcf contre 4 evenioments). Pour déployer avec clickonce dans chaque je change 4 seetings dans le projet et va. (ce que j'aimerais automatiser)

mon seul gotcha est de se remémorer pour "nettoyer tout" après un changement, car l'ancienne configuration est "bloquée" après un renommage manuel. (Qui je pense VA vous corriger le réglage.réglage de la question).

je trouve que cela fonctionne vraiment bien (un jour j'aurai le temps de regarder MSBuild / NAnt)

2
répondu tdrake 2009-02-26 12:43:33

il dit asp.net ci-dessus, alors pourquoi ne pas sauvegarder vos paramètres dans la base de données et utiliser un cache personnalisé pour les récupérer?

la raison pour laquelle nous l'avons fait ici est qu'il est plus facile (pour nous) de mettre à jour la base de données en continu que d'obtenir la permission de mettre à jour les fichiers de production en continu.

exemple de Cache personnalisé:

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
    }
}
0
répondu Prisoner ZERO 2011-05-24 17:44:31

Web.config:

Web.config est nécessaire lorsque vous voulez héberger votre application sur IIS. Web.config est un fichier de configuration obligatoire pour IIS afin de configurer son comportement en tant que mandataire inverse devant Kestrel. Vous devez maintenir un web.config si vous voulez l'héberger sur IIS.

AppSetting.json:

pour tout ce qui ne concerne pas IIS, vous utilisez AppSetting.json. AppSetting.json est utilisé pour Asp.Net hébergement de base. ASP.NET Core utilise la variable D'environnement" ASPNETCORE_ENVIRONNEMENT " pour déterminer l'environnement actuel. Par défaut, si vous exécutez votre application sans définir cette valeur, il sera automatiquement par défaut à l'environnement de Production et utilise "AppSetting.production.json" fichier. Lorsque vous déboguez via Visual Studio, il définit l'environnement de développement de sorte qu'il utilise "AppSetting.json". Voir ce site web pour comprendre comment configurer la variable d'environnement d'hébergement sur Windows.

App.config:

App.config est un autre fichier de configuration utilisé par .NET qui est principalement utilisé pour les formulaires Windows, les Services Windows, les applications Console et les applications WPF. Lorsque vous commencez votre Asp.Net l'hébergement de base via l'application console.la config est également utilisé.


TL; DR

Le choix du fichier de configuration est déterminée par l'environnement d'hébergement que vous choisissez pour le service. Si vous utilisez IIS pour hébergez votre service, utilisez un site web.fichier de configuration. Si vous utilisez un autre environnement d'hébergement, l'utilisation d'une Application.fichier de configuration. Voir configurer les Services en utilisant la documentation des fichiers de Configuration et aussi vérifier la Configuration dans ASP.NET noyau.

0
répondu Alper Ebicoglu 2018-09-10 07:12:46