Clique aqui para ler todos os artigos desta edição
Configuração do ASP.NET
por George Shepherd
Este artigo discute |
Este artigo usa as seguintes tecnologias: |
·Arquivos de configurações do ASP.NET |
XML, ASP.NET, C#
Download: TestRun0408.exe (130KB) |
Chapéu ASP.NET |
|
Mesmo que você já esteja usando o ASP.NET por algum tempo, o quanto realmente sabe sobre os arquivos de configuração do ASP.NET? Embora você já tenha tocado no arquivo Web.config de vez em quando, há algumas nuanças envolvidas na configuração do ASP.NET que talvez não tenha notado. Aqui descreverei a arquitetura por trás dos arquivos de configuração do ASP.NET e mostrarei como as alterações na configuração afetam os programas
Machine.config
Ao instalar o Microsoft® .NET Framework, um arquivo XML chamado Machine.config é instalado no diretório \Windows\Microsoft.Net\Framework\xxx\config (onde xxx é 1.0.3705 para a versão 1.0 do Framework, ou 1.1.4322 para a versão 1.1). O arquivo Machine.config contém as configurações padrão da sua instalação e define os parâmetros que determinam como o .NET funciona em toda a máquina.
Ao percorrer todo o Machine.config, você encontrará nós de todos os tipos de configuração de máquina. Verá
A seção que queremos analisar é
Listagem 1 Grupo da seção system.web Section Group
System.Web, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"/>
System.Web, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"/>
type="System.Web.UI.CompilationConfigurationHandler,
System.Web, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"/>
type="System.Web.UI.PagesConfigurationHandler,
System.Web, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"/>
•••
Nas configurações de
stateConnectionString="tcpip=127.0.0.1:42424"
stateNetworkTimeout="10" sqlConnectionString=
"data source=127.0.0.1;Integrated Security=SSPI"
cookieless="false" timeout="20"/>
Volte ao início do Machine.config e você verá o seguinte no grupo de seção
type=
"System.Web.SessionState.SessionStateSectionHandler,
System.Web, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
allowDefinition="MachineToApplication" />
Esta linha do Machine.config instrui o ASP.NET para que use uma classe chamada SessionStateSectionHandler no conjunto System.Web.dll para administrar o estado. Quando o ASP.NET carregar, uma classe terá que interpretar o elemento de estado da sessão, e SessionStateSectionHandler é a classe que fará isso.
Como você pode ver a partir do código, Machine.config define que o estado da sessão deve ser administrado no processo. Para a maioria das aplicações em servidor único ou em Web farms que mantêm afinidade de máquina ao usar equilíbrio de carga, o estado de sessão "InProc" funciona bem. Contudo, em uma grande Web farm provavelmente será melhor armazenar o estado da sessão em algum outro lugar (por exemplo, em uma máquina executando o SQL Server). Se você alterar as configurações de estado da seção para usar o SQL Server no Machine.config, então todos os aplicativos naquela unidade usarão o SQL Server. Claro, provavelmente você desejará controlar o estado da sessão, aplicativo por aplicativo. É por isso que os aplicativos independentes do ASP.NET contêm um arquivo Web.config.
Web.config
Os arquivos Web.config modificam as configurações padrão estipuladas no Machine.config. Se você fizer uma pesquisa por Web.config, encontrará um bom número deles em sua máquina. Pode haver um arquivo Web.config em \inetpub\wwwroot que controla as configurações de
O Machine.config define as configurações padrão da máquina. Depois disso, o ASP.NET procura o Web.config do diretório \inetpub\wwwroot para obter as configurações. Finalmente, o ASP.NET procura os arquivos Web.config no diretório virtual do aplicativo, e nos seus subdiretórios, para alterar as configurações. Quando o ASP.NET encontrar as configurações estipuladas por um subdiretório do seu aplicativo, será possível (embora improvável) que o Web.config possa ter alterado completamente as configurações padrão.
Os itens a seguir mostram como as configurações dentro dos arquivos Web.config são aplicadas a um aplicativo. O ASP.NET lê os arquivos de configuração e faz as alterações nesta ordem:
•Machine.config (define os valores padrão da máquina)
•\inetpub\wwwroot\Web.config (modifica as configurações do site principal)
•appvirtualdir\Web.config (modifica as configurações do aplicativo)
•appvirtualdir\Web.config (modifica as configurações do aplicativo)
As configurações são modificadas de forma hierárquica, onde cada subdiretório tem a chance de modificar as configurações estipuladas anteriormente, encontradas em cada arquivo Web.config.
Se você não quiser entulhar os subdiretórios do aplicativo com arquivos Web.config, o elemento
É claro que pode haver algumas configurações que você gostaria de manter sem substituí-las. O elemento
Alterando as configurações
O ASP.NET lê esses arquivos de configuração quando o aplicativo é iniciado. As configurações são armazenadas na memória, garantindo um alto desempenho. O ASP.NET também cuida dos arquivos de configuração. Quando você alterar as configurações e salvar o arquivo de configuração, o ASP.NET reiniciará automaticamente o aplicativo e recarregará a configuração atualizada na memória. Isso significa que o domínio do aplicativo que o estiver hospedando dentro do ASPNET_WP.EXE será destruído e recriado. Você perderá qualquer estado em processo ao salvar o arquivo de configuração (como o estado da sessão que não tiver sido descarregada para um servidor de estado).
Embora exista um bom número de configurações padrão dentro do ASP.NET, muitas vezes será útil criar suas próprias definições de configuração. Por exemplo, é uma prática ruim inserir por hardcode dados críticos e maleáveis, como strings de conexão de bancos de dados, diretamente no aplicativo. O que acontece quando um administrador de banco de dados altera a string de conexão (por exemplo, a senha de login)? Você receberá uma ligação telefônica, porque geralmente o aplicativo apresenta problema em casa no meio da noite ou durante um fim de semana! Então você terá que alterar o código fonte, recompilar e reimplementar o aplicativo.
Então, em vez de usar hardcoding, faz sentido usar o arquivo de configuração. Dessa forma, os administradores do sistema serão chamados no meio da noite para alterar a configuração (e você poderá ficar na cama). Vamos analisar algumas das maneiras de armazenar e recuperar configurações com o Web.config.
Usando a seção
Se você tiver somente um valor simples que quiser armazenar no Web.config, o local mais conveniente para isso será o nó
Listagem 2 Recuperando as configurações do aplicativo
Web.config
Form1.aspx.cs
private void Page_Load(object sender, System.EventArgs e)
{
if(!this.IsPostBack)
{
DropDownListappSettingsKeys.DataSource =
ConfigurationSettings.AppSettings.Keys;
DropDownListappSettingsKeys.DataBind();
}
}
private void ButtonGetValueOfAppSettingKey_Click(
object sender, System.EventArgs e)
{
string strKey = DropDownListappSettingsKeys.SelectedItem.Text;
string strValueOfKey = ConfigurationSettings.AppSettings[strKey];
LabelValueOfappSettingsKey.Text = strValueOfKey;
}
Usando NameValueFileSectionHandler
A maioria das definições de configuração tendem a ser pares nome/valor (como no exemplo anterior). A seção
A maneira mais fácil de fazer isso é definir sua própria seção nomeada, mas use o componente NameValueSectionHandler existente para analisá-la e crie um grupo de pares chave/valor que você possa acessar em tempo de execução. A Listagem 3 mostra como definir um grupo de configuração em separado e instruir o ASP.NET para usar o NameValueSectionHandler para analisá-lo. Observe como o Web.config do aplicativo acrescenta um
Listagem 3 Definindo um grupo de configuração em separado
Web.config
type="System.Configuration.NameValueSectionHandler,
System, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089"/>
value="Value for customSection Setting 1"/>
value="Value for customSection Setting 2"/>
Form1.aspx.cs
private void Page_Load(object sender, System.EventArgs e)
{
if(!this.IsPostBack)
{
NameValueCollection nvccustomSection;
nvccustomSection = (NameValueCollection)
ConfigurationSettings.GetConfig("customSection");
DropDownListcustomSectionKeys.DataSource = nvccustomSection.Keys;
DropDownListcustomSectionKeys.DataBind();
}
}
private void ButtonGetValueOfcustomSectionKey_Click(
object sender, System.EventArgs e)
{
string strKey = DropDownListcustomSectionKeys.SelectedItem.Text;
NameValueCollection nvccustomSection;
NvccustomSection = (NameValueCollection)
ConfigurationSettings.GetConfig("customSection");
string strValueOfKey = nvccustomSection[strKey];
LabelValueOfcustomSectionKey.Text = strValueOfKey;
}
Seções de configuração personalizadas
Se você decidir que pares nome/valor simples não são suficientemente bons para as definições de configuração do aplicativo, poderá criar seu próprio componente de handler da seção de configuração. Por exemplo, se você quiser usar seu próprio esquema XML em uma seção do arquivo de configuração, terá que acessar o XML diretamente do arquivo de configuração. A interpretação direta do XML proporciona uma maneira de verificar a sintaxe das informações de configuração e talvez gerar uma exceção se houver algum problema.
É bastante simples criar um componente para ler seções do arquivo de configuração. Basta criar uma classe derivando de IConfigurationSectionHandler e em seguida referenciá-la no seu próprio arquivo Web.config. Veja a interface IConfigurationSectionHandler nas linhas de código a seguir:
public interface IConfigurationSectionHandler
{
object Create(object parent, object input, XmlNode node);
}
O IConfigurationSectionHandler contém um método: Create. O único objetivo de Create é analisar a seção de configuração. Create recebe três parâmetros: dois objetos (parent e input) e um XmlNode. O primeiro parâmetro, parent, representa as definições de configuração em uma seção pai de configuração correspondente, ou seja, as informações de configuração que já foram lidas. O segundo objeto, input, representa um HttpConfigurationContext. Não há muito no HttpConfigurationContext, apenas o caminho virtual até o arquivo de configuração Web.config. Possivelmente você poderia usar o caminho para abrir o arquivo Web.config diretamente. Contudo, o terceiro parâmetro, chamado node, representa o XmlNode que contém as informações de configuração do arquivo de configuração. É assim que você pode ter acesso direto ao conteúdo XML da seção de configuração.
A Listagem 4 mostra a implementação do IConfigurationSectionHandler usado no exemplo. O handler de configuração personalizada configura um componente de logging para a gravação dos pedidos do aplicativo. A classe CustomConfigSettings contém as variáveis (uma string para armazenar o nome de um arquivo de log e um Boolean para armazenar se o logging deve ou não ser feito). A classe CustomConfigHandler é usada pela infra-estrutura do ASP.NET para analisar a seção de configuração personalizada e fornecer as definições para o restante do aplicativo.
Listagem 4 Analisador de configuração personalizado
public class CustomConfigSettings
{
private string _strlogfilename;
private bool _bLogRequests;
public CustomConfigSettings(string strlogfilename, bool bLogRequests)
{
_strlogfilename = strlogfilename;
_bLogRequests = bLogRequests;
}
public string LogFileName
{
get { return _strlogfilename; }
}
public bool LogRequests
{
get { return _bLogRequests; }
}
}
public class CustomConfigHandler : IConfigurationSectionHandler
{
public virtual object Create(object parent, object input, XmlNode node)
{
XmlNode n = node.Attributes.RemoveNamedItem("LogRequests");
if(n == null)
{
throw new ConfigurationException("Attribute expected: LogRequests");
}
bool bLogRequests;
if(string.Compare(n.Value, "TRUE", true) == 0)
{
bLogRequests = true;
// Configure o logger da solicitação aqui...
}
else bLogRequests = false;
n = node.Attributes.RemoveNamedItem("LogFileName");
if(n == null)
{
throw new ConfigurationException("Attribute expected: LogFileName");
}
return new CustomConfigSettings(n.Value, bLogRequests);
}
}
Ao analisar o arquivo de configuração, a classe CustomConfigurationHandler aguarda um elemento que contém dois atributos: LogFileName e um LogRequests, sendo que o segundo representa se o logging deve ou não ser efetuado. A Listagem 5 mostra como o handler da seção de configuração é referenciada no Web.config. Observe que o Web.config define uma nova seção, nomeada como
Listagem 5 Handler de configuração personalizado
type="CustomConfigHandling.CustomConfigHandler,
CustomConfigHandlerLib"/>
LogFileName="c:\requestlog.txt"/>
O CustomConfigHandler.Create é chamado pelo sistema para analisar as informações de configuração. O ASP.NET entrega as informações de configuração que já tiverem sido reunidas (o primeiro parâmetro) e um XmlNode representando o elemento que deverá ser analisado ao método Create. O Create então puxa o LogFileName e o LogFile flag e os retorna em uma instância da classe CustomConfigSettings.
Assim como todas as outras informações de configuração, você pode obter as definições de configuração em tempo de execução. O código a seguir mostra como acessar as informações de configuração personalizadas durante um evento Page_Load.
private void Page_Load(object sender, System.EventArgs e)
{
CustomConfigSettings customConfigSettings;
customConfigSettings = (CustomConfigSettings)
ConfigurationSettings.GetConfig("system.web/customConfigHandling");
if(customConfigSettings != null)
{
LabelLogFileName.Text = customConfigSettings.LogFileName;
LabelLogRequests.Text = customConfigSettings.LogRequests.ToString();
}
}
Observe que o objeto retornado por GetConfig é uma instância de CustomConfigSettings.
Conclusão
Neste artigo analisei como o ASP.NET administra as definições de configuração. O Machine.config contém todas as definições padrão para toda a máquina. Você viu que pode mexer no Machine.config para modificar as definições padrão do ASP.NET, mas isso afeta toda a máquina. Portanto, os aplicativos do ASP.NET procuram por um arquivo Web.config para definir parâmetros específicos do aplicativo. Embora haja um certo número de definições padrão de sistema já definidos, você provavelmente precisará estabelecer suas próprias definições de configuração de vez em quando.
O ASP.NET oferece diversas maneiras de adicionar suas próprias definições de configuração e até mesmo permite que você escreva seu próprio handler de seção de configuração. Embora eu tenha apenas tocado de leve no assunto, ao se aprofundar você verá que o sistema de configuração é extensível e flexível o suficiente para fazer praticamente qualquer coisa que você desejar.