Handling Request too large and identify limits in ASP.NET

For security reasons request sizes are limited by default. This is configurable in the web.config file through the httpRuntime sections maxRequestLength attribute. The value is an integer and it’s default value is 4096 (KB) and therefor is 4,153,344 bytes or 4 MB. The configured values can easily be read using the .NET configuration API: If an request is larger than this value a HttpException is thrown when the HttpRequest properties Forms, Files or InputStream are accessed. The HttpException class has a property named WebEventCode which contains a value of the WebEventCodes lookup class: RuntimeErrorPostTooLarge which is an integer with the value 3004. If you catch this exception you can handle the error in your application code and for instance return a custom error message. But… When hosted in Internet Information Services (IIS) there might be another barrier: The request filtering module. This also has a section to configure the maximal length of a request using the requestLimits section and its maxAllowedContentLength property. By default this is set to 30,000,000 (bytes) and therefore is 29.297 KB or 28.61 MB. If this limit is hit IIS will return a HTTP error 404 with sub status code 13 with the reason phrase “Content Length Too Large”. The .NET configuration API refuses to load this section. And even if accessed raw using the system.webServer sections SectionInformation property and its GetRawXml method the possible inheritance is not reflected. So values configured on server and not on site level divergent from the default cannot be found here. IIS at startup create a configuration file located at *{windows drive}\inetpub\temp\appPools\{appPoolName}\{appPoolName}.config. The IIS application pool identity (the account running our web application) of course has read access to the file. To build up the path we need to get the application pool name at runtime. There is a server variable called APP_POOL_ID that will provide the neccessary information. The following code get the local overwritten values from the web.config, the server level configured, the default value or null if request filtering is not installed: At application startup the configuration can now be validated – request filtering schould always have a bigger value when you want to handle these kind of errors in your application code – and the values of a maximal request length can be read and possibly displayed.

Sitzungslos/Statuslos

http://www.flickr.com/photos/toofarnorth/8670157331/ Aus der RFC 2616: “It is a generic, stateless, protocol” Das heißt, das Fundament auf dem wir aufsetzen ist Sitzungslos. Wenn das Applikations-Framework, egal ob mit Web Forms oder MVC, oder Python, oder PHP, oder Rails…, das respektiert, wird es den Anforderungen des Web gerecht: Skaliert besser – Ich brauche mir im NLB-Szenario (Network Load Balancing) keine Gedanken über Shared Memory machen oder mit dem ASP.NET State-Server einen SPOF (Single Point of Failure) einführen. Skaliert kostengünstiger – Mit MS SQL-Server kann ich State zwar auch *Hochverfügbar* ablegen. Dazu sind dann aber SAN (Storage Area Network), Glasfaser, Switches, Kable, Blech, Strom, Betrieb-System & SQL-Server-Lizenzen zusätzliche Kostenfaktoren. Ist leichter zu testen – Code der auf State reagiert kann nur getestet werden wenn der State reproduzierbar (im Test) erstellt wird. Tests werden komplizierter. Tests dauern länger – letzten Endes auch ein Kostenfaktor. Ist weniger komplex – Code wird verständlicher und transparenter da State sich wie globale Variablen verhält (http://c2.com/cgi/wiki?GlobalVariablesAreBad). Um mal als Beispiel ein Bild zu malen: Wenn ich eine Rakete bauen will um zum Mond zu Fliegen. Bin ich dann schneller auf dem Mond, wenn ich mich mit Thema  Schwerkraft auseinandersetze? Was ist eigentlich State? Oder besser was ist nicht State? Als State werden meist Daten bezeichnet, die temporär sind – also eine sehr befristete Lebensdauer. Häufig ist das aber eine Frage der Perspektive und Granularität. Beispiel E-Commerce Sind es nicht die Daten, der Produkte im Warenkorb, die früher oder später zu Positionen in einer Bestellung werden? Ja und Nein. Natürlich, es sei denn, der User entscheidet sich NICHT dazu die Bestellen-Schaltfläche zu betätigen. Alternativen Cookies In Cookies kann eine begrenzte Datenmenge (1024kb) auf dem Rechner des Users abgelegt werden. VORSICHT: Der User kann die Datei modifizieren. Nicht dass die Produkte im Warenkorb alle nur noch 0 EUR kosten. Auch sensible Daten (selbst wenn verschlüsselt) würde ich hier nicht ablegen: Stichwort Cookie-Hi-Jacking. Je nach Expiration-Date bleiben die Daten hier auch über mehrere Browser-Sitzungen erhalten. HTML5 Web Storage Das neue HTML5 API ermöglicht das Speichern von Dateien im sog. Isolated Storage (http://msdn.microsoft.com/en-us/library/3ak841sy(v=vs.80).aspx) einem Benutzerbezogenen lokalen Verzeichnis. Im Gegensatz zu Cookies, die implizit geladen werden ist es schwieriger diese Daten zu hijacken. Hierbei bleiben die Daten über mehrere Browser-Sitzungen erhalten. http://dev.w3.org/html5/webstorage/ HTML5 Indexed Database API Mit HTML5 kommt eine weitere API. Diese ermöglicht das Ablegen indizierter Daten, wie in einer Datenbank z.B. MS SQL Server, im Isolated Storage. Wie beim Web Storage werden auch hier werden die Daten explizit geladen. Auch hierbei bleiben die Daten über mehrere Browser-Sitzungen erhalten. http://www.w3.org/TR/IndexedDB/ Datenbank Wenn Die Daten (Beispiel E-Commerce) sowieso früher oder später zu einer Bestellung werden, könnte man diese doch einfach so behandeln. Alles was dazu benötigt wird ist eine weiter Spalte in der Datenbank-Tabelle namens z.B. „State“ mit den Werten für „Im Warenkorb“ und „Bestellt“. Hierbei ergeben sich zudem tolle Möglichkeiten: Die Daten bleiben (nur für Angemeldete Benutzer) über mehrere Browser-Sitzungen erhalten Auch über Devices hinweg. Für das Reporting: „TOP 10 Produkte im Warenkorb die aber selten verkauft werden“ und „Verhältnis von Im Warenkorb zu Bestellt“. Nichts desto trotz die *Dateileichen* irgendwann mal aufgeräumt. Der MS SQL Server bietet mit dem SQL Server Agent die Möglichkeit in definierten Intervallen Jobs auszuführen: Backups genauso wie Aufräumarbeiten. Im Zweifel tun es aber auch „Scheduled Tasks“ (http://support.microsoft.com/kb/308569) bzw. von der Konsole die at.exe (http://support.microsoft.com/kb/313289) oder einfach CODE.

PHP und WCF Interop Web Cast

Interoperabilität gehört (fast) zu meinem täglichen Brot :-) Und zwischen Web Services ist das ja auch ganz normal. Ich freue mich daher sehr, dass Microsoft das Thema auch auf dem Schirm hat. Mit dem “Evangelist mit dem Hut” habe ich mich vor ein paar Tagen zusammengesetzt und wir haben einen Web Cast aufgenommen. Jan hat danach noch ein Video-Interview mit mir gemacht, was er in seinem Blog gepostet hat.  Web Cast: PHP - WCF Webservice Interoperabilität MSDN TV: Interview Der Evangelist mit dem Hut a.k.a. Jan Schenk

NRW Conf 09

Auch in diesem Jahr veranstaltet der Just Community e.V. wieder das größte Developer und IT-Pro Community Event. Unter dem Motto „Check-In zum Wissensvorsprung“ holen wir am 28.08.2009 zahlreiche nationale und internationale Speaker nach Wuppertal. Neben den Vorträgen haben Sie natürlich auch dieses Jahr wieder viel Zeit für das Networking mit anderen ITlern aus Nah und Fern. Alle Informationen, wie die Agenda und eine Übersicht über die Speaker gibt es unter http://www.nrwconf.de/. Wir freuen uns, Ihnen auch dieses Jahr sowohl bekannte Gesichter, als auch neue Speaker vorstellen zu dürfen. Die Veranstaltung wurde in diesem Jahr möglich durch unsere Sponsoren: Hewlett Packard, devcoach, Microsoft Deutschland, Brockhaus AG, Itemis AG, sepago GmbH, MT AG, sowie weiteren Unternehmen. Eine weitere Neuerung in diesem Jahr ist der Workshop Day, der am Vortag der eigentlichen Konferenz – sprich am 27.08.2009 – in den Räumlichkeiten unseres Sponsoren Ontaris GmbH stattfindet. Der Developer-Workshop befasst sich mit der Microsoft Web Platform und behandelt die Themen Rich Internet Applications mit Silverlight 3.0 und Web 2.0 Applikationen mit ASP.NET AJAX und JQuery. Die Workshops haben eine begrenzte Teilnehmerzahl (je acht) um den Lernerfolg zu garantieren. Also schnell einchecken…

WCF Sample - Attribute driven Constraints

I posted some Bits Michael and I wrote recently in a WCF Project:The Constraints-Extensions let you easily define attribute based limitations for input, output and return parameters. Limitations can be set to service contracts operations as well as to data contract data member implementations. The constraints validation gets called at runtime by the WCF infrastructure and the behavior will throw a ConstraintViolationException with descriptive messages in case of a constraint gets violated/the validation fails. The following constraint attributes have been implemented:BetweenBetweenExclusiveCompareAgainstEarlierThanNowEarlierThanTodayEqualToGreaterEqualToGreaterThanLaterThanNowLaterThanTodayLessEqualToLessThanMatchMaxElementsMaxLengthMinElementsMinLengthNotBetweenNotEmptyNotEqualToNotNullNullableOneOff·     Data Contract Sample: [DataContract]class TestClass{    [DataMember]    [LessEqualTo(CompareAgainst.FieldOrProperty,"EndDate")]    public DateTime StartDate;     [DataMember]    [GreaterEqualTo(CompareAgainst.FieldOrProperty, "StartDate")]    public DateTime EndDate;     public TestClass(DateTime startDate, DateTime endDate)    {        StartDate = startDate;        EndDate = endDate;    }}   Service Contract Sample: [ServiceContract, ConstraintsValidatorBehavior]interface ITestConstraints{     [OperationContract]    [return:GreaterEqualTo(0)]     int MethodA(        [Between(0,100)]         int a,         [LessEqualTo(20)]         double b,         [NotEmpty]         string c);      [OperationContract]    int MethodB(        [Between(0, 100)]         int a,         [LessEqualTo(20)]         ref double b,         [NotEmpty]         out string c);     [OperationContract]    [return:LaterThanNow]    DateTime MethodC(        [GreaterThan(0)]         int a);       [OperationContract]    void MethodD(        [VerifyObject]         TestClass a);} Download at wcf.netfx3.com

Friday Night Andreas Hoffmann 2nd Lead Of The VfLNiederRhein User Group Picked Me Up Ad We Drove The Long Way Down To The

Friday night Andreas Hoffmann (2nd lead of the VfL-NiederRhein user group) picked me up ad we drove the long way down to the south.   Our destination for Saturday morning was the “Chaostage” event of the .NET user group Deggendorf  (http://dotnet-deggendorf.sefnet.de/). I had a session “Introducing the concepts and architecture of ASP.NET“ in the morning and a second one “Hello WebServices – Message-Oriented Programming for distributed systems” in the evening. We checked in at our hotel in Garching (I won’t tell the name but I’ll tell you a bit about the worst service). Because the waitress served me frozen potatoes with my steak I stood up and walked over to the bar. Just in this moment a voice behind me asked “Is this a codezone keychain? Are you gonna be at Microsoft on Monday?” It was Nicki Wruck (http://spaces.msn.com/members/icebloginfo/PersonalSpace.aspx) the organizer of the ICE 2005 Community together with Frank Solinske (http://spaces.msn.com/members/solinske/PersonalSpace.aspx) IT-Pro Security Guru. Only one nano-second later we drank the first beer together. The geek meet was so exciting that I was just about to forget the bad service of our hotel J Sunday we fetched Stephan Oetzel (http://stephanon.net/) in Poing. We picked up Michael Willers (http://www.staff.newtelligence.net/michaelw/) Developer Security Guru from the Airport to merge the Security guys in the “Hofbräukeller”. Uwe Baumann (http://blogs.msdn.com/uweinside/) discussed about technical stuff with Andreas and me meanwhile. Later Nicki joined us together with Nico Lüdemann (https://www.openbc.com/hp/Nico_Luedemann/) and Carola Helfert (https://www.openbc.com/hp/Carola_Helfert/). Monday - Launch Day – started with the Community GetTogether. Stephan and Andreas and I presented the results of the .NET Summit NRW (our community event). As always the time to do some “networking” was toooooooo short - even if we had at least the day before to talk to a few guys. The Launch Party was great. Steve Balmer’s Launch talk was transmitted per satellite into the Lobby of Microsoft in Germany – Great. The only problem again: So many people and such a small amount of time :-) 

Don't mess with sharepoint...

Carefully said I do not like that sharepoint "hijacks" the Internet Information Server. When you create a virtual directory it is just not accessable because SharePoint took over IIS. Funny fact: This is the second post how to fix issues with IIS and "extension" that cause issues :-) So i decided to hack a small utility serving my needs: ExcludeFromSharepoint.zip (3.46 KB) Enables to exclude applications from sharepoint services through the directory context menu. Install using the "-install" switch; Uninstall using "-uninstall" switch. Because I'm running my machine under a LUA (Limited User Account) i wrote the tool in a way that you can install and uninstall it without administative rights - the contextmenu will be installed per user! if(args[0]=="-install") {     RegistryKey _rkey = Registry.CurrentUser;     _rkey = _rkey.OpenSubKey("SOFTWARE\\Classes",true);     _rkey = _rkey.CreateSubKey("Folder").CreateSubKey("shell");     _rkey = _rkey.CreateSubKey("Exclude from Sharepoint");     _rkey = _rkey.CreateSubKey("command");     _rkey.SetValue(null, App.Application.ExecutablePath + " \"%1\""); } else if(args[0]=="-uninstall") {     RegistryKey _rkey = Registry.CurrentUser;     _rkey = _rkey.OpenSubKey("SOFTWARE\\Classes\\Folder\\shell",true);     _rkey.DeleteSubKeyTree("Exclude from Sharepoint"); } else { ... }   The Implementation works with the webserver extensions version 4.0 or higher       RegistryKey _rkey = Registry.LocalMachine;     _rkey = _rkey.OpenSubKey("SOFTWARE\\Microsoft\\Shared Tools\\" +         "Web Server Extensions",true);         foreach(string _subKeyName in _rkey.GetSubKeyNames())     {         try         {             int.Parse(_subKeyName.Replace(".",""));             RegistryKey _fpKey = _rkey.OpenSubKey(_subKeyName,true);             _fpDir = (string)_fpKey.GetValue("Location");         }         catch(Exception _ex)         {             string _err = _ex.ToString();             break;         }     }   and uses the stsadm.exe from the shared tools of the server extensions.     System.Diagnostics.Process _p = new System.Diagnostics.Process();     _p.StartInfo.FileName = Path.Combine(_fpDir, "BIN\\stsadm.exe");     _p.StartInfo.Arguments = "-o addpath -url http://localhost/" +         _strProjectName + " -type exclusion";     ...     _p.Start();  

Re: Windows Impersonation in ASP.NET

Pierre posted an entry bout impersonation in ASP.NET szenarios. [Pierre]There are several scenario where you have to use the impersonation in ASP.NET. Consider, for example, you have to save and load files from a network share (file server). In that case, if the web site accept anonymous authentications, you have to impersonate a windows user who has enought privileges to access to that resource. You have three choices (I guess): Elevate the ASP.NET process identity - worse case since you could compromise the whole site security Impersonate a windows user during the single call (http://blogs.msdn.com/shawnfa/archive/2005/03/22/400749.aspx) Demand the task to a COM+ server application I think that the last is the best since we have more security and maintenance control[...] I agree with him that "Demand the task to a COM+ server application" is the best way of the three he listed. But for me impersonation it is still a don't. By the way i wanted to post this as a comment but "Comments on this post are closed". Yes this is some criticism on weblogs.asp.net :-) ... So here my opinion as post in my blog: Avoid impersonation! If you need to "redirect a binary that is located on a different box than the webserver to the client" utilize another IIS on the 2nd machine or write a service that returns the binary data.  

.NET 2.0 Only 99.9% backwards compatible?

While re-writing a few WebServices for .NET 2.0 i ran across following: ...public static void WaitProc(object state, bool timedOut){   MyAsyncResult myAsyncResult = (MyAsyncResult)state;   myAsyncResult.OriginalCallback.Invoke(myAsyncResult);}... This compiles without any problems in Visual Studio .NET 2003 but makes the compiler scream (Invoke cannot be called directly on a delegate) untill you change the lines to the following: ...public static void WaitProc(object state, bool timedOut){   MyAsyncResult myAsyncResult = (MyAsyncResult)state;   myAsyncResult.OriginalCallback(myAsyncResult);}...