<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1179473529409580853</id><updated>2012-02-25T14:22:46.471+01:00</updated><category term='NUnit'/><category term='Visual Studio'/><category term='Usability'/><category term='Plugin'/><category term='Extensibility'/><category term='jQuery'/><category term='Transpose'/><category term='CSS'/><category term='Action Filter'/><category term='Application model'/><category term='Javascript'/><category term='jQuery Selector'/><category term='Localization'/><category term='Localisation'/><category term='Vertical Text'/><category term='Scrolling'/><category term='Extension'/><category term='l10n'/><category term='Stored Procedures'/><category term='SCSS'/><category term='jQuery UI'/><category term='Parsing'/><category term='T4'/><category term='Catch All'/><category term='Application_OnStart'/><category term='Refactoring'/><category term='Ajax'/><category term='IHttpModule'/><category term='Testing'/><category term='C#'/><category term='Code Generation'/><category term='ModelBinder'/><category term='Browser Compatibility'/><category term='BLToolkit'/><category term='Validation'/><category term='LESS'/><category term='Magic Values'/><category term='HTML'/><category term='Action Selector'/><category term='Batch'/><category term='Asp.net MVC'/><category term='Asp.net'/><category term='Routing'/><category term='SASS'/><category term='JSON'/><category term='DAL'/><category term='Automation'/><title type='text'>Erratic software development</title><subtitle type='html'>Living in the coded world where bugs are inevitable and success is only optional. By Robert Koritnik</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>22</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-4480014950017224036</id><published>2012-01-29T16:25:00.000+01:00</published><updated>2012-02-03T00:21:48.042+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Usability'/><category scheme='http://www.blogger.com/atom/ns#' term='SASS'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><category scheme='http://www.blogger.com/atom/ns#' term='Extension'/><category scheme='http://www.blogger.com/atom/ns#' term='SCSS'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='LESS'/><title type='text'>CSS3 cross browser SASS... no, SCSS mixins</title><content type='html'>&lt;p&gt;
I like automation that eliminates human factor of forgetting of doing something. Happens to me just like it most likely happens to you. Especially when we do repetitive things. That&amp;#39;s why I&amp;#39;ve written a few posts that are direct result of me striving for automation. May it be the post about &lt;a href="http://erraticdev.blogspot.com/2012/01/running-or-debugging-nunit-tests-from.html"&gt;NUnit test project settings in Visual Studio&lt;/a&gt; that starts NUnit test runner by simply pressing &lt;strong&gt;F5&lt;/strong&gt; button or the &lt;a href="http://erraticdev.blogspot.com/2010/11/running-batch-files-bat-from-within.html"&gt;additional &lt;em&gt;file editor&lt;/em&gt; that automatically executes batch (*.bat) files from within Visual Studio&lt;/a&gt;. Never mind. This one&amp;#39;s related to simplicity, versatility and automation. And CSS3 stylesheets of course.
&lt;/p&gt;

&lt;p&gt;
Actually it&amp;#39;s about the extended CSS syntax that we get by writing SCSS stylesheets (similar to LESS, but more on it later on). SCSS used to be called SASS with its own syntax but now uses CSS syntax hence changed its name. I will be using SCSS acronym from now on because that&amp;#39;s what my following code example uses. If you&amp;#39;ve ever used any of these two you&amp;#39;ll know the benefits of simplified, easier to handle and more powerful style sheets. I have been flirting with this couple for some time now, but on this last project of mine, my flirting became a serious relationship. I started using SCSS. What I will share with you here are a few common mixins that are usable to any web developer.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2012/01/css3-cross-browser-sass-no-scss-mixins.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-4480014950017224036?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/4480014950017224036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2012/01/css3-cross-browser-sass-no-scss-mixins.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/4480014950017224036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/4480014950017224036'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2012/01/css3-cross-browser-sass-no-scss-mixins.html' title='CSS3 cross browser SASS... no, SCSS mixins'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-8645828515282655436</id><published>2012-01-11T01:58:00.001+01:00</published><updated>2012-01-12T23:19:53.661+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Usability'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='NUnit'/><title type='text'>Running or debugging NUnit tests from Visual Studio without any extensions</title><content type='html'>&lt;p&gt;
If you write unit tests and use &lt;a href="http://www.nunit.org/"&gt;NUnit test framework&lt;/a&gt; this may be helpful. I decided to write this simple step by step project configuration because I tend to set it up on every new project but keep forgetting all its details of how to do this. Setting it up is simple and a one-time only process for each test project.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2012/01/running-or-debugging-nunit-tests-from.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-8645828515282655436?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/8645828515282655436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2012/01/running-or-debugging-nunit-tests-from.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/8645828515282655436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/8645828515282655436'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2012/01/running-or-debugging-nunit-tests-from.html' title='Running or debugging NUnit tests from Visual Studio without any extensions'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/-ie4Y28GtZCQ/TwzYtWBM4II/AAAAAAAABvo/GxhHfyaP95g/s72-c/NuGetPackageManagerMenu.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-9038885250429501841</id><published>2011-10-25T16:57:00.002+02:00</published><updated>2011-10-26T08:52:40.772+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Localisation'/><category scheme='http://www.blogger.com/atom/ns#' term='Localization'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Application model'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='l10n'/><category scheme='http://www.blogger.com/atom/ns#' term='Extensibility'/><title type='text'>Application model entity localisation in Asp.net MVC</title><content type='html'>&lt;p&gt;
If you are an Asp.net MVC developer and live in non English speaking country, then you&amp;#39;ve faced the challenge of application localisation. Although frameworks these days support localisation it&amp;#39;s usually not a straightforward process. Especially when it comes to web applications. There&amp;#39;s always a dilemma how to implement localisation and how to choose request locale. Should it follow browser language settings or user preference? Either way there&amp;#39;s an underlying base foundation that can be used to implement each.
&lt;/p&gt;

&lt;p&gt;
This post is not about localisation in general but rather just about application model classes and their property names localisation when presented in Asp.net MVC views by means of &lt;code&gt;Html.LabelFor()&lt;/code&gt; extension methods. There already is a class &lt;code&gt;DisplayNameAttribute&lt;/code&gt; but it lacks capabilities we need.
&lt;/p&gt;

&lt;blockquote&gt;
This blog post is related to .net framework 3.5 and older because there&amp;#39;s a new attribute provided by the .net framework 4 and newer. It&amp;#39;s called &lt;code&gt;DisplayAttribute&lt;/code&gt; which has even more capabilities than those implemented below.
&lt;/blockquote&gt;

&lt;a href="http://erraticdev.blogspot.com/2011/10/application-model-entity-localisation.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-9038885250429501841?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/9038885250429501841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2011/10/application-model-entity-localisation.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/9038885250429501841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/9038885250429501841'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2011/10/application-model-entity-localisation.html' title='Application model entity localisation in Asp.net MVC'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-2889116177373530709</id><published>2011-08-12T18:38:00.002+02:00</published><updated>2011-10-26T08:51:50.318+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery UI'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='Extensibility'/><title type='text'>jQuery UI slider extension that enhances range capabilities</title><content type='html'>&lt;p&gt;
I&amp;#39;m going to provide you with the code that makes it possible to set bounds to range slider handles (minimum and maximum) and some more sugar along with it.
&lt;/p&gt;

&lt;p&gt;
I needed to create a range slider that is a bit smarter than the one provided by jQuery UI library that only allows to set minimum and maximum values for the whole slider, but I needed to set a few things more. I had to provide a range slider that would allow users to select time range between midnight and midday the next day (36 hours all together). These were my requirements:
&lt;ul&gt;
&lt;li&gt;Lower handle can only move to midnight the next day (so it can move between 00:00 and 1d 00:00) - this simply means that time range &lt;strong&gt;must&lt;/strong&gt; start today&lt;/li&gt;
&lt;li&gt;Selected range must be at least 1 hour wide&lt;/li&gt;
&lt;li&gt;Selected range can&amp;#39;t be wider than 24 hours all together&lt;/li&gt;
&lt;/ul&gt;
These were my requirements and although I like jQuery UI plugins/widgets and even though it comes with a &lt;strong&gt;slider&lt;/strong&gt; it doesn&amp;#39;t work as expected. I could of course put it all in my &lt;code&gt;slide&lt;/code&gt; handler, but tha wouldn&amp;#39;t be reusable and it would also not allow me to do some additional things I implemented along. Want to know which ones?
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2011/08/advanced-jquery-ui-range-slider.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-2889116177373530709?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/2889116177373530709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2011/08/advanced-jquery-ui-range-slider.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/2889116177373530709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/2889116177373530709'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2011/08/advanced-jquery-ui-range-slider.html' title='jQuery UI slider extension that enhances range capabilities'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-5507708477148229130</id><published>2011-08-05T20:34:00.004+02:00</published><updated>2011-10-25T11:09:15.728+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Refactoring'/><category scheme='http://www.blogger.com/atom/ns#' term='Magic Values'/><category scheme='http://www.blogger.com/atom/ns#' term='BLToolkit'/><category scheme='http://www.blogger.com/atom/ns#' term='DAL'/><category scheme='http://www.blogger.com/atom/ns#' term='Application model'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>BLToolkit MapResultSet builder</title><content type='html'>&lt;h4&gt;&lt;em&gt;or&lt;/em&gt; How I refactored my seemingly identical methods with generic type parameters&lt;/h4&gt;
&lt;p&gt;
As I&amp;#39;ve &lt;a href="http://erraticdev.blogspot.com/2010/11/t4-template-to-generate-bltoolkit.html"&gt;written in the past&lt;/a&gt; I&amp;#39;m using &lt;a href="http://bltoolkit.net/"&gt;BLToolkit&lt;/a&gt; lightweight ORM on one of my projects. But some parts of it seem very silly actually and I can&amp;#39;t really see why did they decide to do certain parts the way that they did. One of them being the configuration for multiple result sets. You know those where you write TSQL query that returns more than one result. BLToolkit has this nice &lt;code&gt;DbManager&lt;/code&gt; mapping method called &lt;code&gt;ExecuteResultSet()&lt;/code&gt; that takes an array of &lt;code&gt;MapResultSet&lt;/code&gt; objects. And &lt;em&gt;these&lt;/em&gt; you have to prepare yourself first so mapper will actually populate your object lists. Their example looks like this (just the relevant code):

&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;List&amp;lt;Parent&amp;gt; parents = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Parent&amp;gt;();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;MapResultSet[] sets = &lt;span class="kwrd"&gt;new&lt;/span&gt; MapResultSet[3];&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;sets[0] = &lt;span class="kwrd"&gt;new&lt;/span&gt; MapResultSet(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Parent), parents);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;sets[1] = &lt;span class="kwrd"&gt;new&lt;/span&gt; MapResultSet(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Child));&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;sets[2] = &lt;span class="kwrd"&gt;new&lt;/span&gt; MapResultSet(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Grandchild));&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&lt;span class="rem"&gt;// and so on and so forth for each result set&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; (DbManager db = &lt;span class="kwrd"&gt;new&lt;/span&gt; DbManager())&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    db&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        .SetCommand(TestQuery)&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        .ExecuteResultSet(sets);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;
As you can see you have to create an array of &lt;code&gt;MapResultSet&lt;/code&gt; objects of the correct size (using a magic value - and you know &lt;a href="http://erraticdev.blogspot.com/2011/01/generate-enum-of-database-lookup-table.html"&gt;I don&amp;#39;t like them&lt;/a&gt;) and then set an instance to each (again using magic values). Seems tedious? I thought so as well. Hence I&amp;#39;ve done it differently.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2011/08/bltoolkit-mapresultset-builder.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-5507708477148229130?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/5507708477148229130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2011/08/bltoolkit-mapresultset-builder.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/5507708477148229130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/5507708477148229130'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2011/08/bltoolkit-mapresultset-builder.html' title='BLToolkit MapResultSet builder'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-4811389439275784204</id><published>2011-08-02T18:02:00.004+02:00</published><updated>2011-10-21T21:57:35.241+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Vertical Text'/><category scheme='http://www.blogger.com/atom/ns#' term='Usability'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='Browser Compatibility'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><title type='text'>Cross browser headers with vertical rotated text</title><content type='html'>&lt;p&gt;
You&amp;#39;ve probably come across the problem of displaying these kind of tables:
&lt;ul&gt;
&lt;li&gt;many columns&lt;/li&gt;
&lt;li&gt;header column at the top&lt;/li&gt;
&lt;li&gt;content cells display narrow data - flags (yes/no, true/false, y/n, on/off, finite states like yes/no/maybe etc.) or just icons that denote some sort of state as in feature list tables where each cell displays either a check-mark or nothing or green and empty cirles or similar...&lt;/li&gt;
&lt;li&gt;header cells contain much wider data than content cells - more words that take much valuable horizontal space&lt;/li&gt;
&lt;/ul&gt;
If you had to display these kind of tables you&amp;#39;ve probably been thinking how could you make header cells narrower but not clip their content so headers still make sense... The idea is to display header cells as tall cells with vertically displayed text so columns can stay narrow as their content cells need. This way our tables get horizontally usable and don&amp;#39;t take much space. It&amp;#39;s true that header row becomes higher (depending on the amount fo text that you&amp;#39;d like to display, but hey there&amp;#39;s just one header row in the whole table.
&lt;/p&gt;

&lt;p&gt;
Anyway. So if you did struggle with this and also wanted it to display approximately the same on all three major nowadays browsers than you did spend some time solving it. If you didn&amp;#39;t but you think you may in the future, then just use the code I&amp;#39;ll provide here and off you go.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2011/08/cross-browser-vertical-text.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-4811389439275784204?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/4811389439275784204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2011/08/cross-browser-vertical-text.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/4811389439275784204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/4811389439275784204'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2011/08/cross-browser-vertical-text.html' title='Cross browser headers with vertical rotated text'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-356251565367549485</id><published>2011-07-30T02:29:00.003+02:00</published><updated>2011-10-21T21:57:57.842+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Usability'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='Transpose'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Use CSS floats to flow data in columns rather than rows with jQuery .transpose() plugin</title><content type='html'>&lt;p&gt;
I know we have &lt;a href="http://www.w3.org/TR/css3-multicol/"&gt;CSS3 multi-column layout&lt;/a&gt; that makes HTML content flow in columns dead simple but the problem is that only the most modern browsers (as of July 2011) support this CSS3 capability. As you might have guessed this means &lt;em&gt;tough luck&lt;/em&gt; for Internet Explorer users. Microsoft decided that CSS3 column layout is not something developers or better web designers would need so IE still doesn&amp;#39;t support it. &lt;strong&gt;Not even in version 9&lt;/strong&gt; that is.
&lt;/p&gt;

&lt;p&gt;
Even though CSS3 multi-column support got supported recently we have been displaying data in &lt;em&gt;pseudo columns&lt;/em&gt; for some time. We either displayed tables when we had tabular data or used &lt;a href="http://www.w3.org/TR/CSS2/visuren.html#propdef-float"&gt;CSS floats&lt;/a&gt; or &lt;a href="http://www.w3.org/TR/CSS2/visuren.html#display-prop"&gt;CSS inline-blocks&lt;/a&gt; when displaying lists and we didn&amp;#39;t want the list to be long and narrow which makes it hard to use. The nice thing about floating is that elements take as much horizontal space as they can inside container and when individual items are set a fixed width this means that they will display in column-like layout. &lt;strong&gt;The problem&lt;/strong&gt; is though that floated items run in rows meaning that when you have alphabetic text (or numbers) list items they won&amp;#39;t flow in columns as we&amp;#39;re used to ie. in phonebooks. No. Items flow in rows. This makes these kind of lists hard to read and search through. But I have a solution for you. &lt;strong&gt;jQuery plugin that re-arranges your items into columns&lt;/strong&gt; to improve their usability.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2011/07/use-css-floats-to-flow-data-in-columns.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-356251565367549485?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/356251565367549485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2011/07/use-css-floats-to-flow-data-in-columns.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/356251565367549485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/356251565367549485'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2011/07/use-css-floats-to-flow-data-in-columns.html' title='Use CSS floats to flow data in columns rather than rows with jQuery .transpose() plugin'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-7217087610634772032</id><published>2011-03-17T15:19:00.004+01:00</published><updated>2011-10-21T21:58:19.054+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Routing'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Extensibility'/><title type='text'>Removing route values from links/URLs in Asp.net MVC</title><content type='html'>
&lt;p&gt;
I didn&amp;#39;t really know how to properly title this post to make it easily searchable by those who bump into routing-related issue. Words like &lt;strong&gt;arbitrary&lt;/strong&gt;, &lt;strong&gt;ambient&lt;/strong&gt;, &lt;strong&gt;unwanted&lt;/strong&gt;, &lt;strong&gt;unneeded&lt;/strong&gt;, &lt;strong&gt;extra&lt;/strong&gt;, &lt;strong&gt;unrelated&lt;/strong&gt; etc route values popped into my mind, but I decided to title it as it is now.
&lt;/p&gt;

&lt;p&gt;
One of the main pillars of Asp.net MVC is routing. Many applications can just use default route definition to cover all their scenarios but some applications require it to be a bit more complex. Look at this example:

&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;routes.MapRoute(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;    &lt;span class="str"&gt;&amp;quot;CustomerSpecific&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="str"&gt;&amp;quot;Customers/{customerId}/{controller}/{action}/{id}&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;new&lt;/span&gt; { controller = &lt;span class="str"&gt;&amp;quot;Customers&amp;quot;&lt;/span&gt;, action = &lt;span class="str"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;, id = UrlParameter.Optional },&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;new&lt;/span&gt; { customerId = &lt;span class="str"&gt;@&amp;quot;\d+&amp;quot;&lt;/span&gt; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;);&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;routes.MapRoute(&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    &lt;span class="str"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="str"&gt;&amp;quot;{controller}/{action}/{id}&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    &lt;span class="kwrd"&gt;new&lt;/span&gt; { controller = &lt;span class="str"&gt;&amp;quot;Home&amp;quot;&lt;/span&gt;, action = &lt;span class="str"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;, id = UrlParameter.Optional }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
Seems fine? Well it does and it works, but you will have problems when you&amp;#39;ll be anywhere in
&lt;code class="ln"&gt;http://www.domain.com/Customers/&lt;em&gt;n&lt;/em&gt;/...&lt;/code&gt;
and would like to also generate links to parts of your application that are covered by default route definition (second route). Let me show you why.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2011/03/removing-route-values-from-linksurls-in.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-7217087610634772032?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/7217087610634772032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2011/03/removing-route-values-from-linksurls-in.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/7217087610634772032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/7217087610634772032'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2011/03/removing-route-values-from-linksurls-in.html' title='Removing route values from links/URLs in Asp.net MVC'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-316994835913043527</id><published>2011-02-28T20:27:00.007+01:00</published><updated>2011-10-21T21:59:04.951+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Action Selector'/><category scheme='http://www.blogger.com/atom/ns#' term='Routing'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Extensibility'/><title type='text'>Improving Asp.net MVC maintainability and RESTful conformance</title><content type='html'>&lt;style&gt;
table.rest {font-size:8pt;text-align:left;border-collapse:collapse;border-bottom:1px solid #ccc;}
table.rest th {background-color:#eee;border-top:1px solid #ccc;border-bottom:1px solid #ccc;}
table.rest td,
table.rest th {padding:2px 5px;vertical-align: top;}
table.rest .alert {color: #c00;}
table.rest em {color: #999;}
&lt;/style&gt;

&lt;p&gt;
I&amp;#39;ve used Asp.net MVC for a few years now but this &lt;em&gt;issue&lt;/em&gt; I&amp;#39;ve stumbled upon just a few days ago seems something everyday&lt;em&gt;ish&lt;/em&gt; and I wonder how come I&amp;#39;ve never bumped into it. It has to do with Asp.net MVC routing and action method selection. First of all think of default route definition that looks like this:

&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="rem"&gt;// default application route&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;routes.MapRoute(&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="str"&gt;&amp;quot;Default&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="str"&gt;&amp;quot;{controller}/{action}/{id}&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;new&lt;/span&gt; { controller = &lt;span class="str"&gt;&amp;quot;Home&amp;quot;&lt;/span&gt;, action = &lt;span class="str"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;, id = UrlParameter.Optional }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
Mind that &lt;code&gt;id&lt;/code&gt; route value is &lt;strong&gt;optional&lt;/strong&gt;? Yes optional. So it should be perfectly feasible to have two action methods: one with the &lt;code&gt;id&lt;/code&gt; parameter and one without it:
&lt;code class="ln"&gt;public ActionResult Index() { ... }&lt;/code&gt;
and
&lt;code class="ln"&gt;public ActionResult Index(int id) { ... }&lt;/code&gt;
But you&amp;#39;ve probably guessed it? This doesn&amp;#39;t work out of the box. You&amp;#39;ll get a runtime error stating that there are two matching action methods for the current request. A bit strange? I thought so as well. So let&amp;#39;s try and accomplish just that!
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2011/02/improving-aspnet-mvc-maintainability.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-316994835913043527?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/316994835913043527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2011/02/improving-aspnet-mvc-maintainability.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/316994835913043527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/316994835913043527'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2011/02/improving-aspnet-mvc-maintainability.html' title='Improving Asp.net MVC maintainability and RESTful conformance'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_2quejvaDaXc/TQd66QkyWbI/AAAAAAAABAM/ITxBRGo3hjY/s72-c/Diagram.png' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-3372724147129080269</id><published>2011-02-02T03:19:00.035+01:00</published><updated>2011-10-21T21:53:42.798+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Usability'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='Scrolling'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery Selector'/><title type='text'>jQuery animated "scroll into view" plugin (with additional ":scrollable" selector filter)</title><content type='html'>&lt;p&gt;
Sometimes our pages have to deal with long(er) unpaged lists of data. Long enough to fall off the viewable browser window estate. Actually you don&amp;#39;t even have to deal with lists at all. &lt;b&gt;Let me re-define the problem&lt;/b&gt;: when you have a scrollable element on your page (may be the very &lt;code&gt;body&lt;/code&gt; of it) and you need to programmatically scroll to its out-scrolled child element, &lt;b&gt;then this jQuery plugin is just for you&lt;/b&gt;. Now let&amp;#39;s see when we have to do this and what could go wrong.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2011/02/jquery-scroll-into-view-plugin-with.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-3372724147129080269?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/3372724147129080269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2011/02/jquery-scroll-into-view-plugin-with.html#comment-form' title='41 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/3372724147129080269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/3372724147129080269'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2011/02/jquery-scroll-into-view-plugin-with.html' title='jQuery animated &quot;scroll into view&quot; plugin (with additional &quot;:scrollable&quot; selector filter)'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>41</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-7622451376484528506</id><published>2011-01-23T16:53:00.011+01:00</published><updated>2012-01-23T15:33:31.555+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IHttpModule'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Application_OnStart'/><title type='text'>How to correctly use IHttpModule to handle Application_OnStart event</title><content type='html'>
&lt;p&gt;
In one of my previous blog posts (&lt;a href="http://erraticdev.blogspot.com/2010/08/writing-ihttpmodule-thats-able-to.html"&gt;Writing a custom IHttpModule that handles Application_OnStart event&lt;/a&gt;) I&amp;#39;ve been talking about using &lt;code&gt;IHttpModule&lt;/code&gt; to also handle &lt;strong&gt;application start&lt;/strong&gt; event which is a non-documented feature. Sure it works, but you may see some strange behaviour of duplicated (or even multiplicated) functionality being executed. You probably won&amp;#39;t see this with your applications in development, because your local IIS isn&amp;#39;t really heavy duty workhorse, but in production environment you may see this strange behaviour. Investigating it is even a bit more complicated because of the running application serving live traffic. Let me help you. So I will point you in the right direction and more importantly &lt;strong&gt;show you a solution&lt;/strong&gt; that makes things work reliably even on a heavy load IIS.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2011/01/how-to-correctly-use-ihttpmodule-to.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-7622451376484528506?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/7622451376484528506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2011/01/how-to-correctly-use-ihttpmodule-to.html#comment-form' title='26 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/7622451376484528506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/7622451376484528506'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2011/01/how-to-correctly-use-ihttpmodule-to.html' title='How to correctly use IHttpModule to handle Application_OnStart event'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>26</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-3894331782590046667</id><published>2011-01-12T12:11:00.010+01:00</published><updated>2011-10-21T22:00:18.773+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Catch All'/><category scheme='http://www.blogger.com/atom/ns#' term='Routing'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Extensibility'/><title type='text'>Custom Asp.net MVC route class with catch-all segment anywhere in the URL</title><content type='html'>
&lt;p&gt;
&lt;a href="http://www.asp.net/mvc/tutorials/asp-net-mvc-routing-overview-cs"&gt;Asp.net MVC routing&lt;/a&gt; does a fine job with routes that have a finite number of segments. We define them with route URL pattern string. The default provided by the Asp.net MVC project template being &lt;code&gt;{controller}/{action}/{id}&lt;/code&gt;. Most web applications can do everything using only this single route definition and many developers don&amp;#39;t even think beyond this &lt;em&gt;standard&lt;/em&gt;. But sometimes this single route just isn&amp;#39;t enough or it&amp;#39;s just not acceptable.
&lt;/p&gt;

&lt;h4&gt;A real world example&lt;/h4&gt;
&lt;p&gt;
Think of a web site you&amp;#39;re building that has hierarchically organised categories. Like &lt;a href="http://www.amazon.com/gp/site-directory"&gt;Amazon&lt;/a&gt;. We have books, music, electronics, etc. And every top category has sub categories. And so on and so forth. Using default route definition we would access a particular (sub)category simply by:
&lt;code class="ln"&gt;www.domain.com/categories/index/647&lt;/code&gt;
That&amp;#39;s fine, but it&amp;#39;s definitely not human friendly. If we&amp;#39;d change our route URL definition to &lt;code&gt;{controller}/{action}/{id}/{name}&lt;/code&gt; this would already be much friendlier:
&lt;code class="ln"&gt;www.domain.com/categories/index/647/web-development&lt;/code&gt;
That&amp;#39;s something similar (not the same, because we&amp;#39;re still using action names here) to what &lt;a href="http://www.stackoverflow.com"&gt;Stackoverflow&lt;/a&gt; does with it&amp;#39;s questions.
&lt;/p&gt;
&lt;p&gt;
But now think of this super human readable web address:
&lt;code class="ln"&gt;www.domain.com/books/computer-internet/web-development/latest&lt;/code&gt;
This one would display latest web development books. As we can see it defines categories in hierarchical order similar to &lt;a href="http://en.wikipedia.org/wiki/Breadcrumb_%28navigation%29"&gt;breadcrumbs&lt;/a&gt;. All in human readable format. Doing this kind of routing isn&amp;#39;t supported out of the box (because we have an action at the end), but I think we could do better. Let&amp;#39;s try and create a route that supports this.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2011/01/custom-aspnet-mvc-route-class-with.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-3894331782590046667?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/3894331782590046667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2011/01/custom-aspnet-mvc-route-class-with.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/3894331782590046667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/3894331782590046667'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2011/01/custom-aspnet-mvc-route-class-with.html' title='Custom Asp.net MVC route class with catch-all segment anywhere in the URL'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-2353941559480317126</id><published>2011-01-08T16:32:00.008+01:00</published><updated>2011-10-25T11:09:15.711+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Generation'/><category scheme='http://www.blogger.com/atom/ns#' term='T4'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><category scheme='http://www.blogger.com/atom/ns#' term='Magic Values'/><category scheme='http://www.blogger.com/atom/ns#' term='DAL'/><category scheme='http://www.blogger.com/atom/ns#' term='Application model'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Generate enum from a database lookup table using T4</title><content type='html'>
&lt;p&gt;
This is something rather common. You&amp;#39;re building an application that uses database storage in the background. If your database isn&amp;#39;t completely trivial and you&amp;#39;re not fatally in love with &lt;a href="http://en.wikipedia.org/wiki/Magic_number_%28programming%29"&gt;magic values/numbers&lt;/a&gt;, then you probably also use &lt;em&gt;lookup tables&lt;/em&gt; to gain &lt;a href="http://en.wikipedia.org/wiki/Referential_integrity"&gt;referential integrity&lt;/a&gt; when it comes to certain types, codes and similar data. But to follow the &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY software development principle&lt;/a&gt; we want to use these values defined in database on upper layers as well without manually writing any additional code. Because as mentioned &lt;strong&gt;magic values are evil&lt;/strong&gt; regardless of where they&amp;#39;re used.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2011/01/generate-enum-of-database-lookup-table.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-2353941559480317126?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/2353941559480317126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2011/01/generate-enum-of-database-lookup-table.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/2353941559480317126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/2353941559480317126'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2011/01/generate-enum-of-database-lookup-table.html' title='Generate enum from a database lookup table using T4'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-1360761495162821613</id><published>2010-12-27T14:48:00.007+01:00</published><updated>2012-01-04T08:29:53.097+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Parsing'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='Extensibility'/><title type='text'>jQuery parseJSON automatic date conversion for Asp.net and ISO date strings</title><content type='html'>
&lt;p&gt;
This one&amp;#39;s quite common. You asynchronously communicate (a.k.a. Ajax) with your server and get JSON data in return. You most probably use &lt;code&gt;$.parseJSON()&lt;/code&gt; on the client side which actually parses JSON string and returns an object. We&amp;#39;ve all used that. &lt;strong&gt;But&lt;/strong&gt; (yes, there&amp;#39;s always a but) there&amp;#39;s a catch. There&amp;#39;s no defined standard for date serialization, so jQuery will not parse your dates back to dates. What the heck even native JSON parser (these days supported in all major browsers) won&amp;#39;t do that. So you have to do it yourself. Manually. Or, modify default jQuery functionality a bit and get it done automatically.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2010/12/converting-dates-in-json-strings-using.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-1360761495162821613?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/1360761495162821613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2010/12/converting-dates-in-json-strings-using.html#comment-form' title='25 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/1360761495162821613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/1360761495162821613'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2010/12/converting-dates-in-json-strings-using.html' title='jQuery parseJSON automatic date conversion for Asp.net and ISO date strings'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>25</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-6351559307873917985</id><published>2010-12-14T15:27:00.003+01:00</published><updated>2011-10-21T22:01:34.292+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Action Selector'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Extensibility'/><title type='text'>Custom action method selector attributes in Asp.net MVC</title><content type='html'>
&lt;p&gt;
Some of the least customized but very useful extension points in Asp.net MVC are action method selector attributes. We use them all the time without actually knowing, but we may write our own as well and make seemingly complex things trivial.
&lt;/p&gt;

&lt;h4&gt;A real world example&lt;/h4&gt;
&lt;p&gt;
Take for instance &lt;a href="http://www.twitter.com"&gt;Twitter&lt;/a&gt; website. When you first visit their site, you are presented with the anonymous visitor home page that provides search capabilities, trends etc.
&lt;/p&gt;

&lt;p&gt;
But when you&amp;#39;re logged in you see a completely different page. Web address is still the same, but content is completely different. You see &lt;strong&gt;your&lt;/strong&gt; home twitter page where you can send tweets and read your stream.
&lt;/p&gt;

&lt;p&gt;
Using custom action method selector attributes, you can easily differentiate between such requests without using multifaceted controller actions.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2010/12/using-custom-action-method-selector.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-6351559307873917985?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/6351559307873917985/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2010/12/using-custom-action-method-selector.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/6351559307873917985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/6351559307873917985'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2010/12/using-custom-action-method-selector.html' title='Custom action method selector attributes in Asp.net MVC'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_2quejvaDaXc/TQd66QkyWbI/AAAAAAAABAM/ITxBRGo3hjY/s72-c/Diagram.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-2721907258799636523</id><published>2010-12-10T00:15:00.046+01:00</published><updated>2011-10-25T11:09:15.716+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Application model'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Sending complex JSON objects to Asp.net MVC using jQuery Ajax</title><content type='html'>

&lt;p&gt;
&lt;b&gt;jQuery &lt;/b&gt;has great support for sending HTML form data (that is &lt;code&gt;input&lt;/code&gt;, &lt;code&gt;select&lt;/code&gt; and &lt;code&gt;textarea&lt;/code&gt; element values) back to the server using &lt;a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29"&gt;Ajax technologies&lt;/a&gt; by providing two main ways of preparing form data for submission - namely &lt;code&gt;serialize()&lt;/code&gt; and &lt;code&gt;serializeArray()&lt;/code&gt; functions. But sometimes we just don&amp;#39;t have a form to send but rather &lt;a href="http://en.wikipedia.org/wiki/Json"&gt;JSON objects&lt;/a&gt; that we&amp;#39;d like to transfer over to the server.
&lt;/p&gt;

&lt;p&gt;
&lt;b&gt;Asp.net MVC&lt;/b&gt; on the other hand has built-in capabilities of &lt;em&gt;transforming&lt;/em&gt; sent data to strong type objects while also validating their state. But data we&amp;#39;re sending has to be prepared in the right way so default data binder can it and populate controller action parameters objects&amp;#39; properties. We can of course parse values ourselves but then we also loose the simplest yet efficient &lt;a href="http://www.asp.net/mvc/tutorials/validation-with-the-data-annotation-validators-cs"&gt;built-in validation using data annotations&lt;/a&gt; which is something we definitely want to use.
&lt;/p&gt;

&lt;p&gt;
I know I&amp;#39;ve been sending JSON objects back to the server before, but this time I came across a problem that felt odd, since based on my previous experience should work out of the box. To my surprise it didn&amp;#39;t. Let me explain what was going on.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2010/12/sending-complex-json-objects-to-aspnet.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-2721907258799636523?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/2721907258799636523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2010/12/sending-complex-json-objects-to-aspnet.html#comment-form' title='39 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/2721907258799636523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/2721907258799636523'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2010/12/sending-complex-json-objects-to-aspnet.html' title='Sending complex JSON objects to Asp.net MVC using jQuery Ajax'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>39</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-1617577964824135017</id><published>2010-11-19T14:42:00.002+01:00</published><updated>2011-10-25T11:09:15.706+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Action Filter'/><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Validation'/><category scheme='http://www.blogger.com/atom/ns#' term='Application model'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Handling validation errors on Ajax calls in Asp.net MVC</title><content type='html'>
&lt;p&gt;
If you&amp;#39;re developing rich web clients using Asp.net MVC on the back-end, you&amp;#39;ve probably come across this functionality that can be described with these conditions:
&lt;ol&gt;
&lt;li&gt;client side data (may be a form),&lt;/li&gt;
&lt;li&gt;ajax posting of this data (form),&lt;/li&gt;
&lt;li&gt;controller action has strong type parameters,&lt;/li&gt;
&lt;li&gt;controller action processes data and returns anything but a full view (since it was an Ajax call)&lt;/li&gt;
&lt;/ol&gt;
Familiar? Then you&amp;#39;ve come across this problem: »&lt;em&gt;What should be done when validation fails?&lt;/em&gt;«&lt;br&gt;
Seems fairly straight forward, right? Well not so fast my fellow developer friend...
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2010/11/handling-validation-errors-on-ajax.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-1617577964824135017?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/1617577964824135017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2010/11/handling-validation-errors-on-ajax.html#comment-form' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/1617577964824135017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/1617577964824135017'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2010/11/handling-validation-errors-on-ajax.html' title='Handling validation errors on Ajax calls in Asp.net MVC'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-8200591850135139790</id><published>2010-11-04T15:33:00.007+01:00</published><updated>2011-10-21T22:02:48.986+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Batch'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Running batch files (*.bat) inside Visual Studio</title><content type='html'>
&lt;p&gt;
This is something very simple, but very useful. Something Microsoft should&amp;#39;ve put in Visual Studio in the first place long ago. When I develop data-aware applications I usually end up writing database scripts to make it easy to (re)deploy and version control my database model. I usually write several files just to make things controllable and manageable. But deploying them is a different task altogether. And a tedious one as well. I have to fire up SQL Management Studio and then run all those scripts in correct order. Since this is done rather frequently during application development it seems like a very good candidate for automation or simplification. So let&amp;#39;s do just that.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2010/11/running-batch-files-bat-from-within.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-8200591850135139790?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/8200591850135139790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2010/11/running-batch-files-bat-from-within.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/8200591850135139790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/8200591850135139790'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2010/11/running-batch-files-bat-from-within.html' title='Running batch files (*.bat) inside Visual Studio'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_2quejvaDaXc/TNK-932UIrI/AAAAAAAAA_c/4CjhuCl2d68/s72-c/OpenWith.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-5491422965545855347</id><published>2010-11-03T19:18:00.007+01:00</published><updated>2011-10-25T11:09:15.724+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Code Generation'/><category scheme='http://www.blogger.com/atom/ns#' term='T4'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><category scheme='http://www.blogger.com/atom/ns#' term='Magic Values'/><category scheme='http://www.blogger.com/atom/ns#' term='Stored Procedures'/><category scheme='http://www.blogger.com/atom/ns#' term='BLToolkit'/><category scheme='http://www.blogger.com/atom/ns#' term='DAL'/><category scheme='http://www.blogger.com/atom/ns#' term='Application model'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>T4 template to generate BLToolkit compliant stored procedure calls</title><content type='html'>&lt;!--
  * use &lt;h4&gt; for headers
  * use &lt;code&gt; for inline code
  * use &lt;code class="ln"&gt; for full line code
  * code blocks should be formatted using:
    http://www.manoli.net/csharpformat/format.aspx
--&gt;
&lt;p&gt;
Developing data aware applications used to be quite a pain before various helper libraries emerged. At first we used &lt;a href="http://entlib.codeplex.com/"&gt;Enterprise Library&lt;/a&gt; from Microsoft that made things much simpler and standardized. In all the years of development it became very complex or even too complex for usual everyday projects. Anyway. Lately we started using more popular OR/M tools and libraries that go even further and provide a really transparent abstraction layer between our logic and the actual data store (whichever it may be).
&lt;/p&gt;

&lt;p&gt;
Choosing &lt;a href="http://en.wikipedia.org/wiki/Data_access_layer"&gt;DAL layer&lt;/a&gt; technologies isn't always straight forward. You have to choose wisely and think of the scenarios you'll use in your application. The same thing happened to me this last time when I was at the same decision point. &lt;em&gt;Yet again&lt;/em&gt;.
&lt;/p&gt;

&lt;div class="fullpost"&gt;
&lt;p&gt;
I've used &lt;a href="http://msdn.microsoft.com/en-us/library/bb399572.aspx"&gt;Entity Framework&lt;/a&gt; on two past projects (using &lt;a href="http://code.msdn.microsoft.com/EFExtensions"&gt;EF Extensions&lt;/a&gt; along with it to make it simpler to integrate custom occasional stored procedures). Contrary to popular belief I was quite pleased with it even though we had to resort to not so seldom &lt;em&gt;hacks&lt;/em&gt; to make it snappy. Usually provided by stored procedure calls and result materialization. Nonetheless it worked as expected. We still didn't have to write any entity classes, connection lifetime was auto-managed in entity context as well. Entity Framework FTW so to speak. On the downside I should as well mention that speed is not its strength. You use SQL Profiler quite often to analyse those all but easy to grasp &lt;em&gt;spaghetti&lt;/em&gt; T-SQL queries. But things have greatly improved after EF4 was released. Visual Studio integration was of course one of its best strengths that gives you the all familiar drag and click UI without writing XML files. Even though it wasn't fully working in version 1.
&lt;/p&gt;

&lt;h4&gt;Custom complex stored procedures aren't OR/M friendly&lt;/h4&gt;
&lt;p&gt;
But this time I knew this application will be much heavier on the database side with much more complex processes and larger amounts of data. All these will most probably be better processed by stored procedures in the database itself. So I ruled out Entity Framework completely because I would be writing lots of custom materializers and such. But what should one choose instead? Most of these days OR/M libraries don't support custom stored procedures quite well, so I had to rule out &lt;a href="http://msdn.microsoft.com/en-us/library/bb386976.aspx"&gt;LINQ to SQL&lt;/a&gt;, &lt;a href="http://nhforge.org/Default.aspx"&gt;NHibernate&lt;/a&gt;, &lt;a href="http://www.subsonicproject.com/"&gt;Subsonic&lt;/a&gt; and similar as well. I'd use &lt;a href="http://fluentnhibernate.org/"&gt;Fluent NHibernate&lt;/a&gt; anyway since I prefer syntax checked code over XML configuration.
&lt;/p&gt;

&lt;h4&gt;BLToolkit library to the rescue&lt;/h4&gt;
&lt;p&gt;
So I resorted to semi-biased &lt;a href="http://ormbattle.net/"&gt;ORMBattle.NET website&lt;/a&gt; that lists most popular OR/M libraries along with their measured benchmarks. My main requirements for my DAL layer library were:
&lt;ul&gt;
&lt;li&gt;support for all kinds of custom stored procedures and&lt;/li&gt;
&lt;li&gt;automatic result materialization and of course&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;it had to be free&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
After a while (and some checking) I've decided to give BLToolkit a try since it seems it provides exactly what I require. I agree it's not an actual OR/M library, but that makes it even faster. I was thinking of writing a few of my own generic calls that would do just what I need, but I had to to follow the &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY principle&lt;/a&gt;. Ok, BLToolkit it is then.
&lt;/p&gt;

&lt;p&gt;
The good thing is that BLToolkit is fast and provides data materialization. But the bad thing is that you &lt;em&gt;may&lt;/em&gt; end up with lots of magic strings. This is where T4 comes into play. I wanted to avoid writing stored procedures' names and parameters using plain strings, because that's very prone to human errors. Not to mention tedious work and updates when something gets changed on the DB side.
&lt;/p&gt;

&lt;h4&gt;Database side&lt;/h4&gt;
&lt;p&gt;
To make things more generic and structured I had to stick to certain syntax rules on the database side. I didn't want to end up with a single class that has as many methods as there are stored procedures in the database. Certain stored procedures are related to certain common tables, that are usually reflected in some middle layer entity class. For instance if we have a table &lt;code&gt;Person&lt;/code&gt; we will have several stored procedures that will manipulate data around this table and related ones as well. But basically these stored procedures will be somehow related to the &lt;code&gt;Person&lt;/code&gt; database table. We usually name stored procedures that way. At least most of the time:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Person_GetAll&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Person_SaveRelatedData&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
So I shall make this a rule. Part before underscore is related to class name, part afterwards will provide method name. Perfect.
&lt;/p&gt;

&lt;h4&gt;The usual stored procedure call in BLToolkit&lt;/h4&gt;
&lt;p&gt;
If you haven't used BLToolkit before, let me get you up to speed and show you some code, that makes it easy to understand how to execute a parametrised stored procedure call.
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; (var db = &lt;span class="kwrd"&gt;new&lt;/span&gt; DbManager())&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; db&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        .SetSpCommand(&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;            &lt;span class="str"&gt;"Person_SaveWithRelations"&lt;/span&gt;,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;            db.Parameter(&lt;span class="str"&gt;"@Name"&lt;/span&gt;, name),&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;            db.Parameter(&lt;span class="str"&gt;"@Email"&lt;/span&gt;, email),&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;            db.Parameter(&lt;span class="str"&gt;"@Birth"&lt;/span&gt;, birth),&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;            db.Parameter(&lt;span class="str"&gt;"@ExternalID"&lt;/span&gt;, exId))&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        .ExecuteObject&amp;lt;Person&amp;gt;();&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
This represents some code within data repository. Stored procedure populates certain tables (most notably &lt;code&gt;Person&lt;/code&gt; table) and then executes a &lt;code&gt;SELECT&lt;/code&gt; statement as well to return the newly created record (with relations if necessary).
&lt;/p&gt;

&lt;p&gt;
As you may see, this is a very easy and comfortable way of calling stored procedures (can easily call regular queries as well) and having results materialized along the way. But. The problem lies right there in front of our eyes. &lt;em&gt;Magic strings&lt;/em&gt;.
&lt;/p&gt;

&lt;p&gt;
What if we make a typo?&lt;br/&gt;
What if we slightly rename a stored procedure?&lt;br/&gt;
What if we add a few others?&lt;br/&gt;
What if we rename a parameter or its type?&lt;br/&gt;
But the main one is &lt;em&gt;what if we're part of a larger team where each developer's writing a separate part of application&lt;/em&gt; and not everyone is tedious or/and communicative?
&lt;/p&gt;

&lt;p&gt;
The answer to all these questions is &lt;em&gt;use automation&lt;/em&gt;. So let's automate generation of our stored procedure calls with strong typed parameters. The most obvious way of doing this is by using &lt;a href="http://msdn.microsoft.com/en-us/library/bb126445.aspx"&gt;Text Transformation Template Toolkit&lt;/a&gt; or in short &lt;strong&gt;T4&lt;/strong&gt; because it's very well integrated into Visual Studio and works really well. If we use extensions like &lt;a href="http://t4-editor.tangible-engineering.com/T4-Editor-Visual-T4-Editing.html"&gt;Tangible T4 editor&lt;/a&gt; we get nice code highlighting and intellisense support along the way as well.
&lt;/p&gt;

&lt;h4&gt;Stored procedure call after using T4 template&lt;/h4&gt;
&lt;p&gt;
What we'd like to achieve in the end is to get previous code to be called this way:
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; (var db = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataManager())&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; db&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        .Person&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        .SaveWithRelations(&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;            name,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;            email,&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;            birth,&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;            exId&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        )&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        .ExecuteObject&amp;lt;Person&amp;gt;();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
So we can see there're no magic strings any more and we get code intellisense as well, so we don't have to check store procedure names or check parameter names either. The best part is that when anyone else changes parameters or renames a stored procedure we get compile time errors. Code generation FTW!
&lt;/p&gt;

&lt;h4&gt;Gimme gimme gimme code&lt;/h4&gt;
&lt;p&gt;
You can download T4 template from &lt;a href="http://code.google.com/p/bltoolkit-storedprocedures2csharp-t4/"&gt;Google code site&lt;/a&gt;. There's a comment header at the top of the template where you'll find all instructions how to use the template. For now all stored procedures are treated the same. These will probably be next extensions to this template:
&lt;ul&gt;
&lt;li&gt;Support for output parameters&lt;/li&gt;
&lt;li&gt;Handling multi result set stored procedures - there will have to be some naming convention to distinguish these and template will either have to provide some sort of support or skip generation&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;
I'm attaching template comment head here so you can provide some input whether it's readable (just add a comment to this post):
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="rem"&gt;/* BLToolkit stored procedure calls T4 generator          */&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="rem"&gt;/* ------------------------------------------------------ */&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;span class="rem"&gt;/* 1. Fill in variables below this comment head           */&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&lt;span class="rem"&gt;/* 2. Stored procedures must use this notation:           */&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&lt;span class="rem"&gt;/*    ie. "Person_SaveWithRelations"                      */&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&lt;span class="rem"&gt;/*    which will generate:                                */&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&lt;span class="rem"&gt;/*    - a class PersonClass                               */&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;&lt;span class="rem"&gt;/*    - a property DataManager.Person of type PersonClass */&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&lt;span class="rem"&gt;/*    - an instance method Person.SaveWithRelations()     */&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&lt;span class="rem"&gt;/*    - method will have strong typed parameters          */&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;&lt;span class="rem"&gt;/* 3. Save template and use code                          */&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;&lt;span class="rem"&gt;// set your preferred DbManager inherited class name (ie. class DataManager: DbManager { ... })&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; className = &lt;span class="str"&gt;"DataManager"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;&lt;span class="rem"&gt;// provide namespace of your class&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; useNamespace = &lt;span class="str"&gt;"ApplicationName.Data.General"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;&lt;span class="rem"&gt;// provide DB connection name (from .config file) that will be used by your DB manager&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; dbConnectionName = &lt;span class="str"&gt;"DefaultDatabaseConnection"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;&lt;span class="rem"&gt;// provide DB connection string that will be used by this generator&lt;/span&gt;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;&lt;span class="kwrd"&gt;string&lt;/span&gt; connection = &lt;span class="str"&gt;"Data Source=.;Initial Catalog=somedb;User ID=someuser;Password=somepassword"&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;&lt;span class="rem"&gt;/* That's it. Save this file now. */&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/p&gt;

&lt;h4&gt;Provide some feedback&lt;/h4&gt;
&lt;p&gt;
If you have any additional ideas how to enhance or change this template I'm willing to consider your ideas. You can easily provide code snippets that would make it even better. Anyway. I hope you'll use it and that you'll like it.
&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-5491422965545855347?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/5491422965545855347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2010/11/t4-template-to-generate-bltoolkit.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/5491422965545855347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/5491422965545855347'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2010/11/t4-template-to-generate-bltoolkit.html' title='T4 template to generate BLToolkit compliant stored procedure calls'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-360667860828921155</id><published>2010-09-09T02:45:00.005+02:00</published><updated>2011-10-25T11:09:15.720+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Application model'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='HTML'/><category scheme='http://www.blogger.com/atom/ns#' term='ModelBinder'/><title type='text'>Asp.net MVC model binding to List&lt;T&gt;</title><content type='html'>&lt;p&gt;
Asp.net MVC is really a great platform to build performant and very controllable web applications. But sometimes some functionality is scarcely documented if at all. Internet proves (thank you &lt;a href="http://www.google.com"&gt;Google&lt;/a&gt;) to be an invaluable wealth of information in this regard since other developers are usually solving similar problems. But sometimes you either don&amp;#39;t find usable information or you want to test things for yourself as well and learn something new as you go along.
&lt;/p&gt;

&lt;p&gt;
Something similar happened to me on my previous project. I had to dynamically generate a list of objects in the browser and then reliably POST them back to web server so that data would be reliably model bound and validated as well. I wanted to avoid manual validation at all costs because it would unnecessarily overcomplicate server code.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2010/09/preparing-list-of-objects-so-they-can.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-360667860828921155?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/360667860828921155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2010/09/preparing-list-of-objects-so-they-can.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/360667860828921155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/360667860828921155'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2010/09/preparing-list-of-objects-so-they-can.html' title='Asp.net MVC model binding to List&amp;lt;T&amp;gt;'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-5579336908451162026</id><published>2010-08-18T15:46:00.032+02:00</published><updated>2011-10-21T22:03:35.150+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Routing'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='IHttpModule'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='Application_OnStart'/><title type='text'>Writing a custom IHttpModule that handles Application_OnStart event</title><content type='html'>&lt;p&gt;
If you&amp;#39;ve been developing Asp.net web applications you&amp;#39;ve probably come across the &lt;code&gt;IHttpModule&lt;/code&gt; interface, that makes it possible to write reusable request-level event handlers. The same thing can of course be done by writing event handlers inside the &lt;code&gt;Global.asax&lt;/code&gt; codebehind, but then you wouldn&amp;#39;t be able to reuse the same code unless you do a copy/paste.
&lt;/p&gt;

&lt;p&gt;
But &lt;code&gt;Global.asax&lt;/code&gt; codebehind has one particular advantage over your custom modules: &lt;b&gt;it can also attach to application-level events&lt;/b&gt; like application start event for instance. As per documentation, this is not possible with a custom module. Or so I thought...
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2010/08/writing-ihttpmodule-thats-able-to.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-5579336908451162026?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/5579336908451162026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2010/08/writing-ihttpmodule-thats-able-to.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/5579336908451162026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/5579336908451162026'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2010/08/writing-ihttpmodule-thats-able-to.html' title='Writing a custom IHttpModule that handles Application_OnStart event'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1179473529409580853.post-5886583939691966943</id><published>2010-08-17T15:27:00.035+02:00</published><updated>2011-10-21T22:04:18.556+02:00</updated><title type='text'>// I need my own blogpublic void Blog_Start(object sender, EventArgs e){…}</title><content type='html'>&lt;p&gt;
Blogs have been around for a long time (at least by others), but until recently I haven&amp;#39;t really given it a serious thought of starting my own. I simply didn&amp;#39;t really know what to write about and I would spectacularly fail in writing my own memoires or something similar.
&lt;/p&gt;

&lt;a href="http://erraticdev.blogspot.com/2010/08/need-for-my-own-blog.html#more"&gt;Continue reading...&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1179473529409580853-5886583939691966943?l=erraticdev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erraticdev.blogspot.com/feeds/5886583939691966943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://erraticdev.blogspot.com/2010/08/need-for-my-own-blog.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/5886583939691966943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1179473529409580853/posts/default/5886583939691966943'/><link rel='alternate' type='text/html' href='http://erraticdev.blogspot.com/2010/08/need-for-my-own-blog.html' title='&lt;div style=&quot;font:.9em Consolas,Courier New,monospace;&quot;&gt;&lt;div style=&quot;color:#090;&quot;&gt;// I need my own blog&lt;/div&gt;public void Blog_Start(object sender, EventArgs e){&amp;hellip;}&lt;/div&gt;'/><author><name>Robert Koritnik</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-e-EZqxejZ7U/AAAAAAAAAAI/AAAAAAAABw0/GsmDaZgQQRE/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry></feed>
