Wednesday, May 23, 2007
There is a discussion over at Scott Hanselman's site about URL Rewriting in ASP.NET.  I found a similar article about URL Rewriting in ASP.NET on Coding Horror


Synopsis:

Here is a brief synopsis of the problem.  In order to have an http module or handler take care of your url rewriting you must have all requests sent to aspnet_isapi.dll via application extension mapping in IIS 6.

Here is an example:

I want http://whatyour20.com/modules/view-location.aspx?locid=1234

to instead look like:

http://whatyour20.com/locations/yellowstone-national-park/

I do this for several reasons.  The number one reason is SEO.  We want google to give google a good idea of what this page is about.  Obviously the latter url does the much better.  It also gives the users an idea of what the link is about.  Number two, it makes our links hackable.  Number 3, it makes our links more aesthetically pleasing.  I think that is very important.  If I see a url that is meant for people instead of machines, I know the web site creator took some time to dot every i and cross every t.  Number four is the less likely option that I will switch technologies and I don't want to lose all my links and there associated page rank if I switch to a new technology or if Microsoft changes thier extension in the future when the next great thing comes out (Silverlight Foundation Server Pages Advanced with SteelRuby, LOL). 

At whatsyour20.com we use UrlRewritingNet.UrlRewrite to handle all url rewriting duties.  UrlRewrite is an asp.net http module that can rewrite any incoming url and it can handle redirects (301, 302).  This works great but it doesn't get rid of the aspx extension by itself.  In fact no http module or handler can do that because iis uses the file extension to determine which program should handle the request. 

So we need to have IIS route all requests for the domain (http://whatsyour20.com) to the aspnet_isapi.dll as stated above.  The problem with this is that now ALL request will go through asp.net.  We may not need this for all requests.  In fact this can be a problem as it can hurt performance.  I've seen the a claim of 30% performance decrease someplace but I don't remember where right now.  However, it's safe to assume that routing static content through asp.net is just not the best solution.

Solution:

The solution?  After the background information we are finally at the payoff.  This is how we get the goodness of using asp.net url rewriting via http modules and the associated debugging and high level of control this brings us WITHOUT the downside of routing static content through asp.net. 

We access all the static content via a sub-domain.  We use static.whatsyour20.com to server all the static content on the site (Right now this is mostly images).  This is very easy to accomplish.  You simply create another web site in IIS, with the path to the same location as your main domain but using the sub domain.  On this domain you DO NOT route the requests to asp.net.  So on this sub domain all content is handled by IIS because it is static.  You could even take that a step farther and put it on a separate server or use another web server that is optimized for static content. 

Our solution works in a share hosting environment because usually you can set up sub domains on shared hosting.  Also you can usually get all requests routed to asp.net if you put in a ticket and simply ask for it.

A nice side effect of using sub domains is improved performance on the client side.  By increasing the number of hostnames (within reason) we can increase the speed at which the page loads.

Here are a few reference articles on multiple domains names to speed up downloads:
http://yuiblog.com/blog/2007/04/11/performance-research-part-4/
http://www.ajaxperformance.com/?p=33
http://www.die.net/musings/page_load_time/

Conclusion:

Using the presented solution we get a urlrewriting solution that is easy to use and configure (all configuration in web.config), transfers easily between hosting providers (again its all provided by asp.net and web.config) and it improves performance.  I'm still looking for any possible downsides.  Please let me know if you know of any.


Wednesday, May 23, 2007 7:29:14 PM (Central Standard Time, UTC-06:00)  #    Comments [1]
 Sunday, November 19, 2006

One argument script pimps use frequently is that it doesn’t matter what tools a contractor uses to build a house as long as the finished product is the same.

The problem with this argument is that the premise and the analogy are flawed.  Comparing the language to the tools is not quite accurate.  The language is more aptly compared to the building materials used instead of the tools.  The tools would instead include things like the IDE.  With the analogy corrected we now see that the choice of building material is very important.  Using 2x4's instead 2x6's will have a big impact on insulation properties (thicker wall cavities) and cost. 

Is this important?  Absolutely!  

Unfortunately, too many scripting language fans (script pimps) make the same flawed analogy in order to justify the use of their pet language instead of a higher performance language like C++ (or C#, Java, etc).  Scripting languages like Ruby are slower then compiled languages.  Also their nature precludes them from having good IDE support.  This is because much of the meaning (context) can’t be derived until runtime so things like IntelliSense become difficult if not impossible to implement. 

Following the scripter’s analysis we are supposed to assume that scripting languages allow faster construction which I would say is another falsehood.  Yes, some contractors might be able to cut wood just as fast with a handsaw but most want to use as much automation as possible.  Hence, table saws, compound miter saws with laser guides, etc.  These automation tools are closer to Visual Studio than VIM. 

In my experience with Ruby (among other languages) I found that the resulting programs were usually slower, which a scripting language will be by its nature.  I also found that the emperor wears no clothes!  Shockingly, developing in a scripting language is slower because of the lack of automation tools.  Example, try to find all references to variable in a Ruby on Rails project.  Now try the same thing in a C# project using Visual Studio.  In Visual Studio it’s a right click and “Find All References”.  In VIM you could search for the references but you don’t have any support for context.  You don’t know that is the only reference to that variable.  You are using a handsaw instead of the best tools available.

I'm sorry but reality demands that 1 = 1 and slower is slower and speed is important.

Sunday, November 19, 2006 9:53:49 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, September 16, 2005

When it comes to login or authentication schemes for web pages you have a few choices.  

  1. Authenticate with email address and a password.
  2. Authenticate with a user name (either system or user generated) and password.
  3. Authenticate with an account number (or some relevant identifier) and password.
  4. Authenticate with an account number (or some relevant identifier) and pin or other unique identifier (SSN, address, etc).
Each of these schemes has its own unique merits.  The most popular is probably number one above.  The email address is usually one of the easiest logins to remember.  However a potential stumbling block is the situation where multiple unique users share an email address.  It’s hard to believe that this seems logical to a person when email addresses are a free commodity.  

Number two is probably the second most popular as it eliminates the problem from number one, however it introduces the problem that a user must remember some kind of random user name because they probably won’t get the one they want as it will already have been taken.  This increases the possibility of support calls and user frustration.

Number four is becoming more common especially for financial services and other highly regulated or secure environments.  All information is meaningful and unique.

My preference is usually number one.  It’s common and easy to understand and the draw backs are easily remedied by the forcing of a unique email address.

I choose number four as my second choice.  It’s more complex to implement but it provides a higher level of security while using relevant customer/user information.  This would prove especially effective if the required login information changed randomly like many financial institutions authentication schemes.

Friday, September 16, 2005 10:36:15 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, May 17, 2005
I have made some signifigant progress on the ACL security in CHT.  At this point the security is implemented using the visible and enabled proeperties of the controls on the form.  I have wrapped the label, input (textbox, etc) validators and help controls in a an asp:panel (which renders to a div) so that I can simlply hide the whole thing if the user does not have view rights to the object.  For the edit rights I simply disable the input if they do not have edit rights.

At the collection level there are add and delete permissions.  These are pretty easy to establish a link for add and delete just needs to be hidden/visible based on permissions.

An additional issue will be the view permissions in the collection (list) view of the objects.  This could either be handled with templates or with the same visible = true|false scheme. 

So far, so good...
Tuesday, May 17, 2005 8:48:46 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Monday, May 16, 2005

I’ve implemented two things that will enable a fair amount of progress.

The first is a lookup table implementation.  Any name/value pairs can be stored and retrieved from the persistence engine (database, etc).  This makes population combo boxes, list boxes etc very easy.  The search is performed on the object and field.  So for instance a type of car could be search by car & category and then all matching values will be returned.  I have built this into the generation code so that all properties that have an attribute=”choice” will have their UI code load the choices.  This is a possible candidate for caching.

The second system wide feature is field level security.  This is a typical role based security system where each user is assigned one or more roles and each role is assigned permissions to each object, method and field.  This is context driven so that that a customer.name has different permissions then a builder.name.  I’ve built an AccessControlList table in the database and then each field can be queried by its distinguished name i.e. customer.name.  This feature is still experimental but should allow a very manageable security infrastructure for CHT.  This is another candidate for caching.

Monday, May 16, 2005 2:32:31 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, April 26, 2005

The Log4j project has become the de facto logging standard in the java community.  Even with the introduction of built in logging in J2SE 1.4, Log4j still remains the premiere logging framework for java.  The built in library java.util.logging provides convenience but lacks the features of the more mature Log4j.  However, not including the extra appenders and formatting that Log4j offers the function of the two libraries are very similar.  In my opinion you are much better off using the Log4j framework from the start and sticking with it.  The extra functionality has been worth it, at least in my experience.

Another advantage of Log4j is that there are versions of Log4X available for almost every major language.  I also use Log4net for my C# development and it is very nice to be able to switch languages but maintain a very familiar framework.  Almost all the configuration and even the method calls and classes remain virtually unchanged.  One caveat is that Log4net is in some kind of purgatory at the Apache foundation waiting for official project status.  I notice most of their releases are labeled as beta but I have not had any issues with it so far.  Your mileage may vary.

When you need logging, Log4X should be your first choice no matter what language you are using. 

Tuesday, April 26, 2005 4:23:19 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, April 12, 2005
asp.net dev without Visual Studio

I need to research this further.
Tuesday, April 12, 2005 10:52:22 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
I've been thinking recently about a possible maturity index for languages/platforms.  I use Java and C# as my main development languages.  They are very similar in syntax and in function.  If you can do something in one language you can probably do it in the other.  The differences are usally a bit of "syntactic sugar."  The major difference is the maturity of the documentation and of the available "code in the wild" by which I mean demo, samples and full fledged open source libraries.  Java has this in spades.  C# and by association .NET have a lot of this and it is growing each day, however Java has a much bigger head start and a more-open source build-it-yourself mentality. 

Hence the point of this post.  VB was my first language.  I came in to it at version 6, obviously at the end of its life cycle.  However, VB was in its prime.  You could find books, magazines, samples and examples galor.  Programmers had explored every angle of VB, not only had they put on the rubber glove and explored its orifaces but they had opened it up and shined the light on its entrails.  VB was a mature, highly productive platform, which is something that Java is now and C# is definetaly becoming. 

This is not to put down C#.  On the contrary, when C# has the maturity that Java now enjoys it should be a true work of art.  I think that as the .NET platform enters into version 2 we should see C# hit its sweet spot.  The major thing I see holding it back is the lack of open-source (read FREE) software.  Obviously it is designed and publilshed by Microsoft for the intent of selling MS product.  I see promise in that most popular Java utility libraries (JUnit, JDoc, Log4J) have been ported to .NET.  I would like to see more enterprise applications out there.  An open source appserver and web server would be nice.  Some decent object pooling and threading libraries would help. 

I think these will come, its just a matter of maturity.
Tuesday, April 12, 2005 10:21:23 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, April 01, 2005

I found a way to “bind” objects to a web user control so that you don’t have to do this:

   Address a = new Address(….);

   This.txtLine1.Text = a.Line1;
   This.txtLine2.Text = a.Line2;

          
Instead you can just do this:
       

   UserControl.LoadData(a);

Then in the user control you have this:

   Public void LoadData(Address a) 
   {
      FormBinding.BindObjectToControls(a,this);
   }

You can also retrieve the fields once the user has made changes:
 
   FormBinding.BindControlstoObject(a,this);

 
It uses reflection.  It requires that the controls on the form be named the same as the properties of your object.  This actually makes the system very easy to read since your object properties, database fields, stored procedure variables and controls all have the same names. 
 
Here is the original source.

I’ve used this in two separate projects and it has worked very well.  If you combine it with code generation then you really realize some definite time savings with little (if any) performance penalty.  See the link for the article for more info.


Friday, April 01, 2005 9:01:09 AM (Central Standard Time, UTC-06:00)  #    Comments [0]