Finding final/effective web.config values (from inherited configurations)
Are there any apps that can show the final configuration as applied to a particular application directory? What I'm picturing is something along the lines of FireBug's CSS viewer.
Basically, it should show the equivalent single web.config file (as if you only had one), with all the values that apply to the directory in question, with e开发者_Python百科ach element (or even attribute) annotated with its source (the real .config file it came from).
This would greatly help deploying applications into foreign environments (eg, customer sites) where they sometimes have strange configs, that add in global includes (eg, they put the include in machine.config, instead of the web.config for that app) or have allowOverride=false, etc.
None currently exist that are publicly known, however a viewer could easily be written. I would analyze reflected source of the .NET CLR regarding configuration inheritance and value determination. The code logic that calculates the final configuration for a domain is quite specific, so it makes sense no viewer currently exists for your request and this would be a good starting point for a viewer you envision.
Regarding making deployments, comparisons and editing config files easier, I personally recommend trying ASPhere. It's currently the best GUI editor for .NET config files, although it is not open source.
There are of course, additional helpful examples reading / accessing config files:
Setup and App config editor
Read/Write App.Config File with .NET 2.0
Using the Configuration Classes
Runtime Web.config / App.config Editing
And there are special exceptions for sections, such as "processModel" settings. For more information / overview details, see:
MSDN - ASP.NET Configuration File Hierarchy and Inheritance
MSDN - General Attributes Inherited by Section Elements
If you know the config sections you are interested in then this will give you the effective settings as a class specifically for those settings. You could then cast the type and retrieve the settings that way and do the same for any sections you're interested in.
object vals = System.Configuration.ConfigurationManager.GetSection("AppSettings")
However, I don't know of any way to retrieve all of the current config sections if you want to discover all of the sections using code.
(10 years late...)
Another option is to run appcmd.exe list config
(which you can do from within your ASP.NET process) with options to get the effective configuration for your application's location.
This is mentioned in IIS's documentation site:
https://learn.microsoft.com/en-us/iis/get-started/getting-started-with-iis/getting-started-with-appcmdexe#working-with-configuration
To display effective configuration for particular url level, use the
LIST
command of the Config object as follows:%systemroot%\system32\inetsrv\APPCMD list config <URL> /section:SectionName
Where
<URL>
is the configuration path at which the effective configuration should be read, such as"Default Web Site/"
or"Default Web Site/app1/hello.html"
. If not specified, it defaults to server level.
This is the code I use. It's a single .aspx
file you can FTP up and run directly (assuming you don't have anything intercepting requests to .aspx
files)
<%@ Page Language="C#" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Diagnostics" %>
<%
String iisWebsiteName = System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
DirectoryInfo wwwroot = new DirectoryInfo( this.Server.MapPath( "~/" ) );
String appCmdArgs;
const Boolean isAzureAppService = false;
if( isAzureAppService )
{
String applicationHostConfigName = String.Format( @"C:\DWASFiles\Sites\{0}\Config\applicationhost.config", iisWebsiteName );
appCmdArgs = String.Format( "list config \"{0}\" /apphostconfig:\"{1}\"", iisWebsiteName, applicationHostConfigName );
}
else
{
appCmdArgs = String.Format( "list config \"{0}\"", iisWebsiteName );
}
const String appCmdPath1 = @"%systemroot%\system32\inetsrv\appcmd.exe";
String appCmdPath2 = Environment.ExpandEnvironmentVariables( appCmdPath1 );
ProcessStartInfo psi = new ProcessStartInfo( appCmdPath2, appCmdArgs )
{
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
CreateNoWindow = true
};
List<String> stderr = new List<String>();
List<String> stdout = new List<String>();
Int32 exitCode;
using( Process p = new Process() )
{
p.StartInfo = psi;
p.ErrorDataReceived += ( s, e ) => stderr.Add( e.Data );
p.OutputDataReceived += ( s, e ) => stdout.Add( e.Data );
p.Start();
p.BeginErrorReadLine();
p.BeginOutputReadLine();
p.WaitForExit();
exitCode = p.ExitCode;
}
String allErr = String.Join( "\r\n", stderr );
String allOut = String.Join( "\r\n", stdout );
%>
<style type="text/css">
pre { border: 1px inset #999; background-color: #eee; }
</style>
<p>IIS Website Name: <code><%: iisWebsiteName %></code></p>
<p>Command: <code>"<%: appCmdPath2 %>" <%: args %></code></p>
<h3>AppCmd.exe</h3>
<p>Exit code: <%: exitCode %></p>
<h3>Standard Error</h3>
<pre><%: allErr %></pre>
<h3>Standard Output</h3>
<pre><%: allOut %></pre>
精彩评论