ASP.NET - Determine max file upload size at runtime - asp.net

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

Related

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

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

Accessing httpRuntime maxRequestLength programmatically

I've looked around and have yet found a way to sync between the config section for file size and the max I am allowing. Is it even possible?
Is it just best practice to allow very large file sizes in the web.config file and then enforce smaller sizes in your implementations?
Try something like this:
HttpRuntimeSection section = ConfigurationManager.GetSection("system.web/httpRuntime") as HttpRuntimeSection;
So then you get section.MaxRequestLength

web.config, configSource, and "The 'xxx' element is not declared" warning

I have broken down the horribly unwieldy web.config file into individual files for some of the sections (e.g. connectionStrings, authentication, pages etc.) using the configSource attribute.
This is working fine, but the individual xml files that hold the section 'snippets' cause warnings in VS.
For example, a file named roleManager.config is used for the role manager section, and looks like this:
<roleManager enabled="false">
</rolemanager>
However I get a blue squiggle under the roleManager element in VS, and the following warning: The 'roleManager' element is not declared
I guess this is something to do with valid xml and schemas etc. Is there an easy way to fix this? Something I can add to the individual files?
Thanks
P.S. I have heard that it is bad practice to break the web.config file out like this. But don't really understand why - can anyone illuminate me?
Searching a workaround to this matter using Custom Config Files, I found this solution. Dont know if is the correct one.
The problem is that VS cant find a schema to validate your .config (xml). If you are using "native" configuration elements or when you create your custom .config files you must set to every xml document a schema.
By default (in VS9 for example) all xml files use \Microsoft Visual Studio 9.0\Xml\Schemas\DotNetConfig.xsd
but you can add more schemas to use.
Before assigning a schema you must create it.
To create a new Schema based on your own custom.config:
open your custom config file
in menubar XML->Create Schema
save it
To assign your schema:
open your custom config file
in properties panel: click on the browse button [..]
set the 'Use' column to your recently created schema
you can assign as many you want. or have one schema for all your different custom .config files
(Sorry, but my English is not so good)
I think that you get the blue squiggles since the schema of your web.config file doesn't declare these custom config sections that you've 'broken out' into individual files.
In investigating this, I see that some of my solutions have the same issue, but the config sections that are provided from microsoft DON'T have the squiggles. eg: we have extracted the appsettings and connectionstrings out into their own files, and they don't get the squiggles, but our custom ones do.
I tried to view the microsoft schema at schemas.microsoft.com/.netconfiguration/v2.0, but I get a 404 when trying to download it.
What I'm trying to say is if you get a copy of the MS schema and alter it to include your external config files, you should be able to get rid of the dreaded squiggles!
HTH,
Lance

Access compilation element in web.config [duplicate]

Is there any way to access the <compilation /> tag in a web.config file?
I want to check if the "debug" attribute is set to "true" in the file, but I can't seem to figure out how to do it. I've tried using the WebConfigurationManager, but that doesn't seem to allow me to get to the <compilation /> section.
Update:
I know I could easily just load the file like an XML Document and use XPath, but I was hoping there was already something in the framework that would do this for me. It seems like there would be something since there are already ways to get App Settings and Connection Strings.
I've also tried using the WebConfigurationManager.GetSection() method in a few ways:
WebConfigurationManager.GetSection("compilation")// Name of the tag in the file
WebConfigurationManager.GetSection("CompilationSection") // Name of the class that I'd expect would be returned by this method
WebConfigurationManager.GetSection("system.web") // Parent tag of the 'compilation' tag
All of the above methods return null. I'm assuming there is a way to get to this configuration section since there is a class that already exists ('CompilationSection'), I just can't figure out how to get it.
Use:
using System.Configuration;
using System.Web.Configuration;
...
CompilationSection configSection =
(CompilationSection) ConfigurationManager.GetSection( "system.web/compilation" );
You can then check the configSection.Debug property.
TIP: if you need to know how to get a value from a config file, check the machine.config file in your \Windows\Microsoft.net\Framework\<version>\CONFIG folder. In there you can see how all the configuration section handlers are defined. Once you know the name of the config handler (in this case, CompilationSection), you can look it up in the .Net docs.
The easy way to check if you're running in debug mode is to use the HttpContext.IsDebuggingEnabled property. It gets its answer from the compilation element's debug attribute which is the same thing you're trying to do.
After all, you can always load up the Web.config file into an XmlDocument and use an XPath query to find out!
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("~/Web.config"));
doc.SelectSingleNode("/configuration/system.web/compilation/#debug");
However, I suggest you use the Configuration.GetSection method for solution.
CompilationSection section =
Configuration.GetSection("system.web/compilation") as CompilationSection;
bool debug = section != null && section.Debug;
You can always check debug option on the compiler level by enclosing your code with
#if (DEBUG)
#endif
in case that was the idea...
Try using:
HttpContext.Current.IsDebuggingEnabled
Cant you just load the file up as a regular XML File and use XPath to get the nodes?
Try using the ConfigurationManager.GetSection method.

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