Pergunta

Estou desenvolvendo um componente de acesso a dados que será usado em um site que contém uma mistura de páginas clássicas ASP e ASP.NET e precisa de uma boa maneira de gerenciar suas configurações.

Eu gostaria de usar um personalizado ConfigurationSection, e para páginas ASP.NET isso funciona muito bem.Mas quando o componente é chamado via interoperabilidade COM a partir de uma página ASP clássica, o componente não está em execução no contexto de uma solicitação ASP.NET e, portanto, não tem conhecimento de web.config.

Existe uma maneira de dizer ao ConfigurationManager para apenas carregar a configuração de um caminho arbitrário (por exemplo, ..\web.config se minha assembléia estiver no /bin pasta)?Se houver, estou pensando que meu componente pode voltar a isso se o padrão ConfigurationManager.GetSection retorna null para minha seção personalizada.

Quaisquer outras abordagens para isso seriam bem-vindas!

Foi útil?

Solução

Experimente isto:

System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);

Outras dicas

Outra solução é substituir o caminho do arquivo de configuração do ambiente padrão.

Acho que é a melhor solução para o carregamento do arquivo de configuração de caminho não trivial, especificamente a melhor maneira de anexar o arquivo de configuração à dll.

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", <Full_Path_To_The_Configuration_File>);

Exemplo:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", @"C:\Shared\app.config");

Mais detalhes podem ser encontrados em este blog.

Adicionalmente, esta outra resposta tem uma excelente solução, completa com código para atualizar a configuração do aplicativo e um IDisposable objeto para redefini-lo de volta ao seu estado original.Com esta solução, você pode manter o aplicativo temporário Scoped:

using(AppConfig.Change(tempFileName))
{
    // tempFileName is used for the app config during this context
}

A resposta de Ismaeel geralmente funciona, mas encontrei um problema: usar OpenMappedMachineConfiguration parece perder seus grupos de seções herdados de machine.config.Isso significa que você pode acessar suas próprias seções personalizadas (que é tudo o que o OP deseja), mas não as seções normais do sistema.Por exemplo, este código não funcionará:

ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath);
Configuration configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;  // returns null

Basicamente, se você colocar um relógio no configuration.SectionGroups, você verá que system.net não está registrado como SectionGroup, portanto é praticamente inacessível pelos canais normais.

Encontrei duas maneiras de contornar isso.A primeira, da qual não gosto, é reimplementar os grupos de seções do sistema, copiando-os de machine.config para seu próprio web.config, por exemplo.

<sectionGroup name="system.net" type="System.Net.Configuration.NetSectionGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <sectionGroup name="mailSettings" type="System.Net.Configuration.MailSettingsSectionGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <section name="smtp" type="System.Net.Configuration.SmtpSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </sectionGroup>
</sectionGroup>

Não tenho certeza se o aplicativo da web será executado corretamente depois disso, mas você pode acessar a seçãoGroups corretamente.

A segunda solução é abrir seu web.config como uma configuração EXE, que provavelmente está mais próxima da função pretendida:

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = strConfigPath };
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;  // returns valid object!

Ouso dizer que nenhuma das respostas fornecidas aqui, nem a minha nem a de Ishmaeel, estão usando essas funções como os designers do .NET pretendiam.Mas isso parece funcionar para mim.

Além da resposta de Ismaeel, o método OpenMappedMachineConfiguration() sempre retornará um Configuration objeto.Então, para verificar se ele carregou, você deve verificar o HasFile propriedade onde true significa que veio de um arquivo.

Forneci os valores de configuração para o Word hospedado .nET Compoent da seguinte maneira.

Um componente da biblioteca de classes .NET sendo chamado/hospedado no MS Word.Para fornecer valores de configuração ao meu componente, criei winword.exe.config na pasta C:\Program Files\Microsoft Office\OFFICE11.Você deve ser capaz de ler os valores das configurações como faz no .NET tradicional.

string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];

A resposta aceita está errada!!

Ele lança a seguinte exceção ao acessar a propriedade AppSettings:

Não é possível converter o objeto do tipo 'System.Configuration.DefaultSection' para o tipo 'System.Configuration.AppSettingsSection'.

Aqui está a solução correta:

System.Configuration.ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "YourFilePath";
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

Para ASP.NET use WebConfigurationManager:

var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/");
(..)
config.AppSettings.Settings["xxxx"].Value;

Use processamento XML:

var appPath = AppDomain.CurrentDomain.BaseDirectory;
var configPath = Path.Combine(appPath, baseFileName);;
var root = XElement.Load(configPath);

// can call root.Elements(...)

Isso deve funcionar:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "newAppConfig.config);

Fonte : https://www.codeproject.com/Articles/616065/Why-Where-and-How-of-NET-Configuration-Files

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top