How to read system value from web.config and use in ASP.NET MVC C# method - asp.net

I'm working on a ASP.NET MVC3 web application (not written by me) which has a max upload size of 100MB. Now this web application gets installed on server machines for customers so it would be nice if this value max upload size was configurable for each customer. They have access to edit the web.config for the web application if need be.
Now there's a value in the web.config like so:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="104857600" />
</requestFiltering>
</security>
</system.webServer>
Also there's another value here which appears to be similar:
<system.web>
<httpRuntime maxRequestLength="104857600" executionTimeout="360" />
</system.web>
That 104857600 bytes appears to be the 100MB file upload limit. However on changing the value I discovered that this isn't the authoritative value and it wasn't obeying the new limit. So after some more digging I found somewhere else in the C# code was a hardcoded value public const double MaxContentSize = 104857600 and another C# method was using that value to accept/deny the Ajax file upload.
So what I think I'd like to do is replace that hard coded number in the code so it reads from the value in the web.config. Then at least anyone can change that value in the web.config when they deploy the website.
Can you do something like this?
MaxContentSize = ConfigurationManager.systemWeb.httpRuntime['maxRequestLength'];
I've seen some examples using appSettings in the web.config e.g.
<appSettings><add key="MySetting" value="104857600" /></appSettings>
then accessing it like:
ConfigurationManager.AppSettings["MySetting"]
But that would mean adding a custom value in there and now we'd have 3 places to change it in the web.config. Anyone got an idea how to do it properly?
Many thanks

You can do something like:
int maxRequestLength = 0;
HttpRuntimeSection section =
ConfigurationManager.GetSection("system.web/httpRuntime") as HttpRuntimeSection;
if (section != null)
maxRequestLength = section.MaxRequestLength;

There seems to be no easy way to read the system.webServer section, because it is marked as "ignored" from machine.config.
One way is to parse the XML of the web.config file directly:
var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
var section = config.GetSection("system.webServer");
var xml = section.SectionInformation.GetRawXml();
var doc = XDocument.Parse(xml);
var element = doc.Root.Element("security").Element("requestFiltering").Element("requestLimits");
string value = element.Attribute("maxAllowedContentLength").Value;

Try:
var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("/")
var section = (System.Web.Configuration.SystemWebSectionGroup)config.GetSectionGroup("system.web")
var maxRequestLength = section.HttpRuntime.MaxRequestLength

Related

ASP.NET - Determine max file upload size at runtime

I have several places on my site where I have helptext telling users what the maximum allowed file upload size is. I would like to be able to have this be dynamic, so that if I change the request limits in the web.config file, that I don't have to go and change the form instructions in a bunch of places. Is this possible using ConfigurationManager or something?
Since you didn't give any further Details: As pointed out here, you have 2 options to set a size Limit for your whole Application.
Depending on that you need to approach this a little differently:
If you use <httpRuntime maxRequestLength="" /> you can get the Info through WebConfigurationManager
//The null in OpenWebConfiguration(null) specifies that the standard web.config should be opened
System.Configuration.Configuration root = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(null);
var httpRuntime = root.GetSection("system.web/httpRuntime") as System.Web.Configuration.HttpRuntimeSection;
int maxRequestLength = httpRuntime.MaxRequestLength;
In Priciple you should be able to do the same with <requestLimits maxAllowedContentLength="" />. But the system.webServer-Section in WebConfigurationManager is declared as IgnoreSection and can't be accessed. It may be possible to change this behaviour in application.config or similiar of IIS. But since (in my case) even the .SectionInformation.GetRawXml() failed, I tend to declare this a lost case.
My Solution in this case would be to access the Web.config-File manually:
var webConfigFilePath = String.Format(#"{0}Web.config", HostingEnvironment.MapPath("~"));
XDocument xml = XDocument.Load(System.IO.File.OpenRead(webConfigFilePath));
string maxAllowedContentLength = xml.Root
.Elements("system.webServer").First()
.Elements("security").First()
.Elements("requestFiltering").First()
.Elements("requestLimits").First()
.Attributes("maxAllowedContentLength").First().Value;
Another Solution to this is proposed by #Roman here using Microsoft.Web.Administration.ServerManager for which you need the Microsoft.Web.Administration Package

How can I reference an appSetting in a different part of web.config

I have my appSettings defined in a separate config file called Appsettings.Dev.Config, and I include that file inside my web.config file like so
<appSettings configSource="ConfigFiles\AppSettings.Dev.config"/>
Lets say one of the settings in the file is
<add key="MailerEmailAccount" value="myemail#myserver.com" />
Can I access the value of the setting MailerEmailAccount elsewhere inside web.config? How?
Nope, the web configuration file cannot pull "settings" from itself; it's not dynamic at all. The only sort of dynamic functionality is the ability to include other .config, but that's just a "suck all these settings in as if they were part of me" kind of thing.
It might be possible if you create a custom ConfigurationSection that pulls the value from appSettings.
Here's an article that explain how to create a custom configuration section:
http://haacked.com/archive/2007/03/12/custom-configuration-sections-in-3-easy-steps.aspx
I don't know if this is what you're looking for, but it's the only way I can think of to read a web.config setting from within the web.config.
EDIT
I haven't tested this, but maybe something like this would work?:
[ConfigurationProperty("localName", IsRequired = true, IsKey = true)]
public string LocalName
{
get
{
return this["localName"] as string;
}
set
{
this["localName"] = WebConfigurationManager.AppSettings.Get(value);
}
}

Retriving a setting in a Web.Config <configSections>

I have this code in my Web.Config file:
<configSections>
<section name="myWebAppSettings" type="System.Configuration.SingleTagSectionHandler" />
</configSections>
<myWebAppSettings isTestEnvironment="true"/>
I need retrieve my value isTestEviroment from Global.asax
At the moment I use with no sucess:
bool isTestEnvironment = ConfigurationManager.AppSettings.GetValues["isTestEnvironment"];
What I'm doing wrong here?
NOTES: I do not assume my Web.Config file is right so please feel free to change it if I did not written correctly. Thanks for your help on this!
ConfigurationManager.AppSettings retrieves values from the AppSettings configuration element, not your custom section.
You need to use:
var section = (HashTable)ConfigurationManager.GetSection("myWebAppSettings");
bool isTest = Boolean.Parse(section["isTestEnvironment"].ToString());

URLCompression + Response Filter Conflict

I have IIS 7.5 with URL compression enabled for dynamic content. I wanted to add a response filter to remove modify the rendered html and for some reason I kept getting garbage data while filtering.
The code for the response filter's write method is below:
Encoding encoding = HttpContext.Current.Response.ContentEncoding;
string html = encoding.GetString(buffer);
html = regFindFollow.Replace(html, new MatchEvaluator(AddFollowNoFollowAttribute));
byte[] outdata = encoding.GetBytes(html);
This starts to work when I remove URL compression from web config. Am I missing something here? Is there an order for response filters that can be specified?
Config I am using is
<urlCompression doDynamicCompression="true" dynamicCompressionBeforeCache="true" />
Changing the config with
<urlCompression doDynamicCompression="true" dynamicCompressionBeforeCache="false" />
Fixed this. I suppose during the execution module received compressed html and couldn't parse it.

Resource file for a Custom ASP.net control (.ascx) InvalidOperationException

I have a control containing some text which I want to get from a resx file, I thought I could just create a file called ControlName.ascx.resx but that doesn't seem to be working.
I'm using
label1.InnerText = (string)GetLocalResourceObject("default");
To get the value from the resource file but it keeps throwing up an InvalidOperation Exception.
Am I right about how resx files work or does it only work for Pages?
I have the same code working on an aspx page.
When you call GetLocalResourceObject from within a user control, you are actually calling TemplateControl.GetLocalResourceObject, which will look in the wrong place for the resource file. You need to call HttpContext.GetLocalResourceObject instead.
protected string HttpContextGetLocalResourceObjectAsString(string message)
{
string path = HttpContext.Current.Request.Path;
return (HttpContext.GetLocalResourceObject(path, message) as string);
}
Now you can do
label1.InnerText = HttpContextGetLocalResourceObjectAsString("default");
Per the documentation:
Gets a page-level resource
http://msdn.microsoft.com/en-us/library/system.web.httpcontext.getlocalresourceobject.aspx
Edit- added
It may be less work to just add the string to the web.config and grab it from there.
<configuration>
<appSettings>
<add key="LoggingSystemId" value="B2F085A9-6EC1-4CBF-AF8B-B17BFA75AD81"/>
<appSettings>
...
referenced as follows:
logger.SystemId = System.Configuration.ConfigurationManager.AppSettings["LoggingSystemId"];
Of course, you'll need a reference to the System.Configuration dll.
A year or so later, but i think this is what you're after?
var resource = HttpContext.GetLocalResourceObject(TemplateControl.AppRelativeVirtualPath, termType.ToString());
Mark answer if that's the one!

Resources