Why Microsoft's Browser Developer Tools suck

Ok, this is kind of a rant post. I acknowledge that Microsoft is really really doing a good job at certain (developer) spots (ASP.NET, Visual Studio, IIS, SQL Server, …). But NOT at the browser developer tools – I’m listing my issues here, hoping the IE-Team will listen and make the world better for everybody. Dev Tools Pinning Location Why can’t I pin the developer toolbar on the right side as in every other browser. Screens with 4:3 have gone. Widescreen is the standard. Pinning at the bottom makes no sense to me (in most cases). Edge IE11 Firefox Chrome Opera Open Developer Tools At Start Tab In Edge the ability to open developer tools is disabled … for whatever reason:   In internet explorer with about:blank this was possible… Q: So how can i network trace an initial request? A: Go somewhere else, Hit F12, then do what you originally wanted to do #this-is-not-intuitive Opera, Chrome, Firefox Explicit enablement of network trace (<Win10) Thank you for fixing that on Windows 10 – in IE11 on Win 8.1 it’s still disabled by default. Please offer an update for IE/<Win10. Initiator of network request (<Win10) Thank you for fixing that on Windows 10 – in IE11 on Win 8.1 it’s still shows <script> and not the specific script with line and char. Please offer an update for IE/<Win10. IE11.0.9600.18161/Win8.1 IE11.63.10586.0/Win10 Dockability of Tools Window Thank you for fixing that on Edge – In IE 11 the tools window cannot be docked with [Win] + [left|right]. Dark Theme FF developer edition does it. Chrome can do it. IE and Edge lack a dark theme, seriously. Call to action So c’mon Edge Devs. Make the web developers life easier. surprise us. you can do better!

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.

Using credentials based on a SecureString that is disposed

Today I was building a credential store API. One implementation against the Windows Credentials Manager (CredMan), the other one persisting information in a database. Of course the data is not persisted in clear text. I use either the MachineKey functionality or a RSA certificate based encryption.So far so good, but I want the passwords to be secure in memory to. The .NET Framework already has a Type built in for that purpose: SecureStringThe SecureString class implements the IDisposable interface and having a property in a class of that type means losing control of the destruction.The implementation will return ICredentials instances to authenticate mostly web requests or provide proxy authentication. So I created a test to figure out how the combination of NetworkCredential and SecureString behaves. All green – It’s possible to use a NetworkCredential object that is constructed with a SecureString even after the SecureString has been disposed. Looking inside the credential object using redgate's Reflector reveals that NetworkCredential internally uses the copy method to clone the SecureString. When a normal string is passed to the constructor it is wrapped into a SecureString also.Sadly the NetworkCredential class does not implement IDisposable. So the issue is carried out to the user code.Keep in mind: When using NetworkCredential to call SecurePassword.Dispose() after the credentials aren’t required any more!

Batch processing Visual Studio ProjectItems with the Nuget Package Management Powershell Console

Today I helped a customer to minify and bundle a bunch of JavaScript files. We used WebGrease triggered from MsBuild to do the job. The next thing to do is changing the BuildAction property on all non-bundled-and-minified JavaScript files so that only minified and bundled files are published. Here is my script: Hope that helps

Bye bye RFC2616, Welcome RFC 723X

The IETF has published a bunch of new RFCs to update HTTP/1.1 specs and make the 15 year old 2616 obsolete: RFC 7230: Message Syntax and Routing RFC 7231: Semantics and Content RFC 7232: Conditional Requests RFC 7233: Range Request RFC 7234: Caching RFC 7235: Authentication RFC 7236: Authentication Scheme Registrations RFC 7237: Method Registrations RFC 7238: the 308 status code RFC 7239: Forwarded HTTP extension Here I listed a few changes: Userinfo (i.e., username and password) are now disallowed in HTTP and HTTPS URIs, because of security issues related to their transmission on the wire. Header fields that span multiple lines ("line folding") are deprecated. Bogus Content-Length header fields are now required to be handled as errors by recipients. Gateways do not need to generate Via header fields anymore. The limit of two connections per server has been removed. An idempotent sequence of requests is no longer required to be retried. The requirement to retry requests under certain circumstances when the server prematurely closes the connection has been removed. Also, some extraneous requirements about when servers are allowed to close connections prematurely have been removed. The semantics of the Upgrade header field is now defined in responses other than 101 The Expect header field's extension mechanism has been removed due to widely-deployed broken implementations. The "about:blank" URI has been suggested as a value for the Referer header field when no referring URI is applicable, which distinguishes that case from others where the Referer field is not sent or has been removed. The following status codes are now cacheable (that is, they can be stored and reused by a cache without explicit freshness information present): 204, 404, 405, 414, 501. The 201 (Created) status description has been changed to allow for the possibility that more than one resource has been created. Method Registry: http://www.iana.org/assignments/http-methods/http-methods.xhtml Status Code Registry: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml Happy reading, happy implementing!

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.