Posts Tagged ‘Web Development’
Meanwhile, Back At CodePlex…
Just a quick update — I’ve been working on Flow Based MVC Controllers some more and hope to do a blog post about them in the next couple days…
For now, I’ve moved some of my other MVC projects onto CodePlex so there is a better home for them (than my own website of course
)
Mvc Content Marker
A few months ago I wrote some code that allowed you to write to different parts of the page using inline code — You probably know it isn’t easy to add a stylesheet or script to a different part of the page since after render code has finished you can’t go back and write over it.
This code makes it so you can place a marker on the page and then write back to it no matter where you are at. It also supports forward looking markers (meaning markers that haven’t been added to the page yet) so it makes it easy to add scripts to the footer of your page from higher up in the document.
As it turns out Spark has something similar to this — but if you aren’t ready to jump into Spark then this still might be handy for you. (Spark is cool, don’t get me wrong though)
Mvc WebForm
Mvc WebForm does exactly what you think it does — It lets you place a WebForm inline with your Mvc code. I isn’t perfect at all and in all honestly was just to see if it was possible. As it turns out you can have basic event handling, button clicks, data grids — whatever — and it works directly in your Mvc Views. Neat stuff even if it is evil.
I expected to be shunned by the development community with this but surprisingly I got several ‘thank you’s and ‘good job’s — Funny how that works out sometimes.
Flow Based MVC Controllers
I’ve been working on a project lately that has required that a controller follows a series of logical steps before it reaches the end. I don’t want users to access the last step until earlier steps have finished. The process also branches into separate paths depending on their selections.
One of the things that bugged me is I hated having so much logic devoted to checking to see if steps had been done before I continued. For example, checking if an image had been uploaded OR if they selected one from a gallery. Most likely I could simply create a property that checked for the state of things, but I wanted to come up with a reusable way to manage the flow of a controller.
The Flow
So here is an example of what kind of flow would go through this. This controller allowed a customer to provide a custom image or choose one from a gallery. The requirements at the end change depending on what a user selects.
Right now I’ve only developed some rough code — but here is a basic idea of how the flow can be controlled automatically.
The Basics
This first example shows the basic idea behind identifying a method as requiring a step to complete. An attribute can be applied to
//for now, the flow process uses extension methods instead of an inherited class
using MvcFlow.FlowExtensionMethods;
//A controller for MVC
public class ShopController : Controller {
//required override to check steps automatically
protected override void OnActionExecuting(ActionExecutingContext filterContext) {
//extension method to check an action in the flow
this.ProcessStep(filterContext);
}
//this step has no requirements so it can be browsed to at any time
public ActionResult Index() {
returns this.View();
}
//this has no requirements but it does APPLY a step if the validation is successful
public ActionResult ValidateUser(string username, string password) {
if (this.PasswordIsCorrect(username, password)) {
//an extension method to update the steps for the flow
this.ApplyStep(Steps.UserValidated);
return this.RedirectToAction("SelectType");
}
//if the process doesn't apply the next allowed step then it can't proceed
else {
return this.RedirectToAction("Index");
}
}
//this step cannot be executed until Steps.UserValidated has been applied
//which is done in the successful validation step
[StepRequires(Steps.UserValidated)]
public ActionResult SelectType() {
return this.View();
}
//snip...
The important thing to notice is that there are only three things required to make this process work.
- Override the OnActionExecuting method to perform the validation. By overriding this step we can make sure an action is allowed to be executed — and if not, redirect the user.
- Add an attribute to describe step requirements. The attribute
StepRequiresallowed us to define what steps must have been completed before they can execute this action. - Apply steps after successful validations. If requirements have been met then the step can be saved and a new set of actions will open up.
Removing And Branching
Here is another example of the code that shows how flow can be managed…
//snip...
//this step requires validation has happened -- but it also removes if
//they have selected certain future steps. This means if someone browses back
//to the page then they are required to answer the question again
[StepRequires(Step.ValidatedUser)]
[StepRemoves(Step.SelectCustom | Step.SelectGallery)]
public ActionResult ChooseType() {
return this.View();
}
// BRANCH 1
// Custom --------------------------
//Applies the SelectCustom option -- but also removes the option for
//the other branch (if it was even found)
[StepRequires(Step.ValidatedUser)]
[StepRemoves(Step.SelectGallery)]
public ActionResult SelectCustom() {
this.ApplyStep(Step.SelectCustom);
return this.RedirectToAction("UploadImage");
}
//This step requires that both the validation and select custom steps have been applied
[StepRequires(Step.ValidateUser | Step.SelectCustom)]
public ActionResult UploadImage() {
return this.View();
}
// BRANCH 2
// Gallery --------------------------
//Applies the SelectGallery option -- but also removes the option for
//the other branch (if it was even found)
[StepRequires(Step.ValidatedUser)]
[StepRemoves(Step.SelectCustom)]
public ActionResult SelectGallery() {
this.ApplyStep(Step.SelectGallery);
return this.RedirectToAction("ShowGallery");
}
//This step requires that both the validation and select gallery steps have been applied
[StepRequires(Step.ValidateUser | Step.SelectGallery)]
public ActionResult ShowGallery() {
return this.View();
}
Unfortunately, the attributes are a bit difficult to read but the general idea is to break the flow of the controller into two parts — each existing separate from each other but within the same controller.
You’ll notice in these steps we can use our enumerated type to create more than one requirement for an action (for example Step.ValidatedUser | Step.SelectCustom ). We can also use the RemovesStep attribute to automatically move back the current point of the flow.
Too Confusing?
I wrote a lot of the code to do this process today but I’m looking for some thoughts about this process. Is this too much work? Too confusing? Not really helpful?
Do you spend enough time managing flow in your applications that a framework like this could help?
ERROR: Cacographic Solecism Directive Encountered **
** Unreadable Error Message Found
I’m pretty picky about user interface with a lot of the projects I work on ranging from the user experience to the design and layout. Ever since I read Steve Krug’s, Don’t Make Me Think, I find myself spending a lot of time reading over the same content again and again trying to simplify them to their shortest possible length.
One section that has always been a focal point for me has been error messages or really any dialog that requires user interaction. However, I’m not just talking about the cryptic, developer designed error messages like ‘IOError Detected!’ or ‘Generic GDI+ Error’ (I especially hate that error).
No, the error messages I’m talking about are messages that don’t really help the user — or error messages that help the user, but too late into the message.
Here is an example from Netflix. It isn’t a bad message but I think that it could be improved.

The Anatomy Of An Error Message
Not all situations are the same but I try to write all of my error messages in the following order.
- What happened in a short sentence.
- Give the user options and solutions
- Explain in slightly more detail what happened but only if the problem may happen again or it helps them understand how to avoid the problem.
What Happened? Few Words Should Say It All — Or Don’t Bother!
I try to stay brief with everything… well, except blog posts, of course. If you’ve visited my latest project CustomWebmail.com then you’ll notice I try to keep everything to a sentence or two. I’ve had a lot of feedback that people like how short and to the point everything is.
Your error message should be the same – short and to the point. Don’t waste a lot of time explaining why it broke or telling them what happened in the background that caused the failure.
In some cases you don’t even need to present the problem as an error message especially if the resolution is simple. The Netflix message is a good example of this. The message feels a lot like an error – but should it? Or should it be presented that this message is the natural result of leaving the page idle?
User Options – Empower The User Quickly
Giving the user the control to fix the problem right away should immediately follow the title of the error – not an explanation of the problem. Include only as many options are really relevant.
I’d even go as far to say that even Yes and No buttons should have a description as well. Explain what the yes and no buttons will do — even if it seems obvious. A button that reads “Yes; Save my document to the server” is much clearer than simply a button that says “Yes” or “OK”.
The Netflix error says to reload the page — manually. Why? Chances are they already have a mouse nearby — why not simply say Click Here To Continue Your Movie! and handle reloading their page when they press the button?
They do offer a suggestion but they don’t offer to do it for you, which I think would improve this box a little more.
Explain The Problem: But Only If It Matters
I’m sure this part would be a point of contention to many people. Often we feel like we need to tell the user what is wrong but also why there was a problem. Clearly, each situation is different, but more often than not I think that the ‘why’ is irrelevant. Here are a few times I think explaining why is important.
- The user might make the same mistake again (ex. invalid e-mail addresses)
- The problem might make a user think your service is broken and you need to explain that it is either normal procedure or a problem from somewhere else.
- To answer why a response is required (ex. input form that wants information a user might not be comfortable in providing)
More or less, if the reason why doesn’t affect the user then you don’t need to share it. If your function SaveUserData() crashes and returns an ‘Unable to save to /Data/Profiles/Users.txt’ error then don’t tell your user. Simply saying ‘We’re sorry – We had a problem saving your information’ is more than enough information to explain why they need to do the same step twice.
My Version
Remember, I like to nitpick this kind of thing. I realize that error messages in my own programs could be improved as well. That said, here is a sample that I think would work better for visitors.

With this message, we are to the point faster and offer a solution to the problem immediately. I also dimmed the error message some and highlighted the actions that could be taken so the user would be drawn to it quickly. I’m sure this message could be improved upon even more but this seems like a good start.
How much time do you spend making your messages as short and as simple as possible?
** The author spends a lot of time reviewing content — but not his own blog — so if you see any typos then please be forgiving
Introducing CustomWebmail.com
I like blogging but the past few weeks (maybe months?) my posts have gotten a little sparse — but for good reason! I’ve been working hard on completing another project and this weekend was the launch date!
What Is CustomWebmail.com?
I do a lot of contract work ranging from programming applications to fixing other in-house developed applications. One job that always gets a lot of interest is customizing a corporate Outlook Web Access login page. I’ve done several of these for a variety of companies.
The idea behind the website was to move the entire customization process online and then present the user with a nice neat .zip file of the resources they would need to install on their webmail server.

How It Was Made
The site uses ASP.NET MVC, C# and jQuery — I couldn’t find a use for my jLinq project, unfortunately
. The site does a lot of interesting things in the code like checking remote sites via HttpWebRequest or creating HTML and image slices using the System.Drawing classes. Over the next few weeks I’ll go over some of the more interesting parts of how the site works.
For now, if you have any Server Admin buddies that might be interested, please tell them about http://www.CustomWebmail.com.
MVC Post Round-Up
I thought I’d bring back a few of my previous ASP.NET MVC posts just in case they were missed before.
Include Stylesheets and Scripts To Your Header With MVC
A while back I wanted to include some stylesheets in my header of a MVC View, but I wanted to do it from a WebControl. Since you’re using inline code the standard Page properties like “header” aren’t going to do you much good (since you’re already in the render event). Fortunately, with a little magic with the HttpContext.Current.Response.Filter stream, you can make all the changes you need before the content is sent to the user.
Using WebControls With Inline MVC
Just for fun I wanted to see if it was possible to actually create WebControls that worked inline with MVC Views. It took a little bit of work to do (it actually ended up spanning 4 different posts) but it finally came together fairly well.
This series was actually inspired at the idea of just rendering controls inline, without postbacks.
- Part 1 – The ViewState Problems
- Part 2 – Simple Postbacks!
- Part 3 – Coming together! Source Code
- Part 4 – How It Works… sorta…
Combining MVC with Existing Web Services
I like the idea behind WebServices, but the hassle of creating SOAP envelopes and modifying headers makes them difficult to use in places other than .NET applications. Being able to create a MVC Controller that automatically maps to an existing WebService would make it easier to use the same functionality, but all from a standard HTTP call.
Anonymous Types (Sorta MVC related…)
If you’ve worked with Anonymous Types in MVC then you’ve probably noticed that you can’t just pass them into your view and expect them to be available. Personally, recommend creating a unique class for anything that you’re passing into a view – but if you’re looking for something that you can use in a hurry, then this Anonymous Type wrapper class might come in handy. Just pass in an anonymous type and the class does the rest!
You can change values, assign new methods — basically you have a little bit of dynamic programming goodness all wrapped into a single .NET class!
Outlook Web Access via iPhone
You may have seen my post a little while back about how I was starting to do some iPhone development for my job. For the most part the app is nothing more than a nice pretty front end to a handful of Web Services (hint: last blog post was along the same lines)
In any case, I’d rather my first attempt at iPhone development be a throw away project since I’m going to probably going to have to start over several times.
Learning Through Development
Whenever I offer up advice to a new programmer on what is the best way to learn programming I always say – “write a program that does something you want — you’ll learn a lot along the way and have motivation to finish it.”. Learning Objective-C was no exception for me.
Even though we use Exchange for our e-mail server at work, we don’t have the “Active Sync” enabled so you can’t link up with the iPhone through the built in e-mail application. So, instead, I decided to go a different route — use the existing Outlook Web Access and parse the HTML.
So with a couple of nice Regular Expressions and some HTTP calls we have a nice clean display of all the e-mails in my mailbox. Yep, that’s right — screen scraping via HTML… a little cheesy, but not bad since it works even if Exchange isn’t configured to allow it!
This was a perfect example of writing an application that met my need and allowed me to learn a new language at the same time… of course I’m not suggesting that I’m an Objective C expert or anything but at least now I can ditch my BlackBerry!
Hey, Who Puked On My Screen… Oh Wait, That’s Objective C
I’m definitely a spoiled programmer. Using .NET and C#/VB has definitely shielded me from some ugly languages out there. Objective-C is the kind of stuff that makes babies cry.
Developing iPhone is WAY different that anything that you have ever done in .NET. You’re adding all sorts of weird things like IBOutlet and IBAction so you can link them around all over the place — it is definitely a new experience. I’m going to have to write a ‘C# Developers Guide To iPhone Development’ to maybe save some other poor guy a lot of grief.
Still a .NET Guy
Getting into new languages and technologies on different platforms is always a good idea. You gain added perspective while increasing your skill sets (not to mention you look better on paper for your next job). Even if you don’t want to buy a Mac and play with the iPhone you can always tinker with a myriad of other languages on any number of free operating systems — Go do it!!
Don’t think that I’m converting – If anything using a Mac this much has solidified why I’m still die-hard Windows/ASP.NET/PC…
…But then again… MonoDevelop for Mac is looking kinda slick…
Combining WebServices with MVC
I always liked the concept behind WebServices. Having a single place to store a bunch of complex but commonly used functions is a great way to decrease complexity of other programs that all sit on the same network. If you’re like me and tend to do a lot of intranet applications, a web service can prevent a lot of duplicate code.
My only real problem with WebServices was having to use SOAP. Adding a Web Reference to a project wasn’t that big of a deal but if you ever wanted to just call a function real quick, say from a script file (yes, I do VBScript occasionally… ick) then it isn’t quite as I’d prefer. You end up spending more time making sure your XML is well formed and less time on the logic inside your quick script.
MVC helps get around that problem by allowing you to perform normal HTTP calls and plug all your arguments into the query string or the body of the request – something much easier to do. The problem, however, is that you end up losing the convenience of using a WebService with other applications.
A Simple Solution
The idea here is to create a controller that acts as a wrapper to a WebService. By doing this we can override a few methods on our Controller that use reflection to invoke the matching method on the WebService. Also, because the Controller is still a unique class, we can still attach any number of Actions to it as we normally would. Below is some code that I wrote the other day. It isn’t battle tested so if you use it be sure to verify it does everything that you need it to do.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Mvc;
using System.Reflection;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.IO;
namespace Interface.Controllers {
/// <summary>
/// Abstract wrapper that handles calling WebService methods on behalf of a controller
/// </summary
public abstract class WebServiceControllerWrapper<T> : Controller where T : WebService {
#region Constructors
/// <summary>
/// Creates a new Controller Wrapper for a WebService
/// </summary>
public WebServiceControllerWrapper() {
this.Service = Activator.CreateInstance<T>();
}
#endregion
#region Properties
//The service that is being used for this call
private T Service { get; set; }
#endregion
#region Overriding Methods
//finds the correct method for the WebService method
protected override void HandleUnknownAction(string actionName) {
//find if the method exists
MethodInfo method = this.Service
.GetType()
.GetMethods()
.Where(found =>
found.IsPublic &&
found.Name.Equals(actionName, StringComparison.OrdinalIgnoreCase) &&
found.GetCustomAttributes(typeof(WebMethodAttribute), true).Count() > 0
)
.FirstOrDefault();
//if no method was found, just give up
if (method == null) { return; }
//check if all the arguments were found
List<object> arguments = new List<object>();
ParameterInfo[] parameters = method.GetParameters();
foreach (ParameterInfo param in parameters) {
//check if this argument was found
object arg = this.ValueProvider[param.Name].ConvertTo(param.ParameterType);
arguments.Add(arg);
}
//with the arguments try and call the result
object result = method.Invoke(this.Service, arguments.ToArray());
//if there is a return value, serialize it and write it
this.Response.ContentType = "text/xml";
if (method.ReturnType != null) {
//if this is an XElement of some kind, just use it as is
if (result is XObject) {
//write the string
using (StreamWriter writer = new StreamWriter(this.Response.OutputStream)) {
writer.Write(result.ToString());
}
}
else {
//try and serialize it
XmlSerializer serialize = new XmlSerializer(result.GetType());
serialize.Serialize(this.Response.OutputStream, result);
}
}
}
#endregion
}
}
The idea here is to inherit this class instead of the standard Controller class and provide the name of the WebService we want to wrap around as our Generic argument. For example…
//that's about it - actions are mapped automatically to the correct method on the webservice
public class AccountController : WebServiceControllerWrapper<AccountWebService> { }
By doing this, when our controller receives an Action, is checks the WebService instance for the same method and then tries to call the method with the arguments it finds as part of the request!
And that’s it! A quick and simple way to map incoming actions to a matching method on a Web Service!
The Return Type
I’m not sure the best way to handle the return type at this time. It seems to me that the XmlSerializer should be sufficient for object with the exception of Xml which should probably just be written out as a string. If you have a suggestion on a better way to respond to incoming requests, please let me know.
Remember: This is just some quick and dirty code – This needs some more polish and exception handling before I’d use it in a real project, but at least it might help you get going in the right direction.
Build A Smarter Loop With C#
One of the first things every programmer learns in how to loop through an array of information. We learn how to do for, foreach, while loops but then we never really improve on them. For the most part the standard loop is as far as a programmer goes.
It seems to me that loops should be more intelligent than that. In fact we often write code that uses the loop for additional information. It isn’t uncommon to see a loop check if it is an even or odd index or the first or last value.
Modestly Smarter Loops
I really like lambdas a lot – in fact probably, too much. Being able to pass an delegate around like an argument definitely can be abused but in some cases it can make for some really elegant code. Let’s look at some code that can improve working with arrays.
namespace LoopExtensions {
//Some comments removed for brevity...
#region Extension Methods
/// <summary>
/// Handles looping through collections with additional details
/// </summary>
public static class LoopExtensionMethods {
public static IEnumerable<T> Each<T>(this IEnumerable<T> collection,
Action<ElementDetail<T>> each) {
return LoopExtensionMethods.Each<T>(collection, 0, collection.Count(), each);
}
public static IEnumerable<T> Each<T>(this IEnumerable<T> collection,
int start,
Action<ElementDetail<T>> each) {
return LoopExtensionMethods.Each<T>(collection, start, collection.Count(), each);
}
public static IEnumerable<T> Each<T>(this IEnumerable<T> collection,
int start,
int end,
Action<ElementDetail<T>> each) {
Action<ElementDetail<T>, T> handle = (detail, item) => { each(detail); };
return LoopExtensionMethods.Each<T>(collection, start, end, handle);
}
public static IEnumerable<T> Each<T>(this IEnumerable<T> collection,
Action<ElementDetail<T>, T> each) {
return LoopExtensionMethods.Each<T>(collection, 0, collection.Count(), each);
}
public static IEnumerable<T> Each<T>(this IEnumerable<T> collection,
int start,
Action<ElementDetail<T>, T> each) {
return LoopExtensionMethods.Each<T>(collection, start, collection.Count(), each);
}
public static IEnumerable<T> Each<T>(this IEnumerable<T> collection,
int start,
int end,
Action<ElementDetail<T>, T> each) {
//verify the ranges
if (start < 0 || end > collection.Count()) {
throw new ArgumentOutOfRangeException();
}
//perform the work
foreach (T value in collection) {
each(new ElementDetail<T>(value, start++, end, collection), value);
if (start == end) { break; }
}
return collection;
}
}
#endregion
#region Detail Information Class
/// <summary>
/// Contains a summary of information about the item current in the loop
/// </summary>
public class ElementDetail<T> {
#region Constructors
internal ElementDetail(T value, int index, int total, IEnumerable<T> collection) {
this.Value = value;
this.Index = index;
this.Total = total;
this.Collection = collection;
}
#endregion
#region Loop Information
public int Index { get; private set; }
public int Total { get; private set; }
public T Value { get; private set; }
public IEnumerable<T> Collection { get; private set; }
#endregion
#region Value Properties
public T Previous {
get {
return !this.First
? this.Collection.ElementAt(this.Index - 1)
: default(T);
}
}
public T Next {
get {
return !this.Last
? this.Collection.ElementAt(this.Index + 1)
: default(T);
}
}
public bool Last {
get { return this.Index == (this.Total - 1); }
}
public bool First {
get { return this.Index == 0; }
}
public bool Outer {
get { return this.First || this.Last; }
}
public bool Inner {
get { return !this.Outer; }
}
public bool Even {
get { return this.Index % 2 == 0; }
}
public bool Odd {
get { return !this.Even; }
}
#endregion
#region Collection Properties
public int StepNumber {
get { return this.Index + 1; }
}
public float PercentCompleted {
get { return (((float)this.Index / (float)this.Total) * 100); }
}
public float PercentRemaining {
get { return 100 - this.PercentCompleted; }
}
public int StepsCompleted {
get { return this.Index; }
}
public int StepsRemaining {
get { return this.Total - this.Index; }
}
#endregion
}
#endregion
}
Now that is a lot of code but if you review over it you’ll find that it is a set of extension methods that can be used with IEnumerable. The basic idea is that we can perform our loop within a delegate that accepts additional information about the elements in our loop.
So here is a quick example…
string[] items = {
"Apple",
"Orange",
"Grape",
"Watermellon",
"Kiwi"
};
items.Each((item) => {
Console.Write("{0} > ", item.Inner ? "Inner" : "Outer");
if (!item.First) { Console.Write("Previous: {0}, ", item.Previous); }
Console.Write("Current: {0} ({1})", item.Value, item.StepNumber);
if (!item.Last) { Console.Write(", Next: {0}", item.Next); }
Console.WriteLine(" -- {0}% remaining", item.PercentRemaining);
});
// Output
// Outer > Current: Apple (1), Next: Orange -- 100% remaining
// Inner > Previous: Apple, Current: Orange (2), Next: Grape -- 80% remaining
// Inner > Previous: Orange, Current: Grape (3), Next: Watermellon -- 60% remaining
// Inner > Previous: Grape, Current: Watermellon (4), Next: Kiwi -- 40% remaining
// Outer > Previous: Watermellon, Current: Kiwi (5) -- 20% remaining
Normally you would simply write all the comparisons within your loop and then use them as needed. Instead, in this code, we pass in an additional parameter that contains shortcuts to many common comparisons you might find inside of loops. By doing this we improve readability and focus on what the loop is doing.
Whats Wrong With The Old Way
Nothing! Writing your comparisons inline can be advantageous since you aren’t doing any more work than you need to do. However, in some cases, the improved readability would make a big difference in the quality of the code. Consider the two snippets of MVC code and decide with one is easier to read.
<ul>
<% foreach(SiteMapNode node in breadcrumb) { %>
<li class="item <% =(breadcrumb.IndexOf(node) % 2 == 0 ? "item-even" : "item-odd") %>" >
<% if (breadcrumb.First().Equals(node) || breadcrumb.Last().Equals(node)) { %>
<strong>
<% } %>
<a href="<% =node.Url %>" >
(<% =(breadcrumb.IndexOf(node) + 1) %>) : <% =node.Text %>
</a>
<% if (breadcrumb.First().Equals(node) || breadcrumb.Last().Equals(node)) { %>
</strong>
<% } %>
</li>
<% } %>
</ul>
Or the same code using a loop helper…
<ul>
<% breadcrumb.Each((node) => { %>
<li class="item <% =(node.Even ? "item-even" : "item-odd") %>" >
<% if (node.Outer) { %><strong><% } %>
<a href="<% =node.Value.Url %>" >
(<% = node.StepNumber %>) : <% =node.Value.Text %>
</a>
<% if (node.Outer) { %></strong><% } %>
</li>
<% }); %>
</ul>
This example shows using only the ElementDetail class but of course you could use the other extension method that also supplies the value by itself.
Write Code For Humans Not For Computers
Everyone has heard the advice before – more or less, readability is probably the most important part of your code. The computer can read both of those examples easily whereas a human might need to think for a moment before they are positive what the code does.
In any case, this simple but effective approach can transform previously unreadable code into works of programming art… or something like that…
WebForms : FrontPage For Programmers
Yeah – I said it. I called WebForms FrontPage for programmers – whadaya goin’ to do?
Now before people start throwing hate mail at me its worth pointing out that up until MVC I used WebForms for all of my web development. In fact, I really do like WebForms. I think that they are especially great for whipping out quick internal projects that normally draw away from the time you could use developing something useful.
But, as much as I like WebForms, I think that too often they spew out more crap than value. If FrontPage was the way for a non-technical person to make a website then WebForms is the way for a non-web developer to make a website.
A Simple Example
(It’s worth noting my measurements are based on uncompressed HTML – I’m mostly pointing out the differences between output created by the developers – not the content that is compressed down the wire.)
Well here is a page that really rubs me wrong…

Why? Nothing bad about it – the page looks pretty good… until you look under the hood at the source code. Once you start digging into it you find that the page is a whopping 123K and of that 28K is in the ViewState — clearly something that could have been done away with. You can also tell that ASP.NET gave a bunch of the elements on the page a unique ID even though they aren’t going to be referenced by any sort of Javascript. How about the id ctl00_BaseBody_FadingHeroEmbeddedSliverlight1_FadingHeroEmbeddedSL_ HeroBottomTitleShortDescriptionDivID (I had to put a break in the middle).
ASP.NET really does an incredible job abstracting the web so that a desktop programmer can jump right into web development, sometimes even using drag-and-drop controls *shudder*. It seems to me that web development ought to be done by people that understands the model.
Here is an example where you can tell that web developers had constructed it. It pains me to show it but I think it is relevant here since they are direct competition.

Yeah, it’s the website of the enemy. But if you go over the page there is roughly the same amount of information (if not more) but their page is only 25K (smaller than the ViewState alone on the previous example). Even if you compare all of the resources on the two pages, the Apple site loads about 30K less in stylesheets and scripts than the Microsoft site. It is worth mentioning that the Apple site does load more images but their entire pages is full of large, high quality images — which is something that grabs attention much better than text. Not only that, but the Apple site actually does stuff!
Why? If you look at the source code you can an immediate difference between the two. The source code on the Apple page is cleaner, better designed and smaller. There is no ViewState or unnecessary ids for elements on the page. Everything (appears) to have been placed onto the page through careful consideration and not generated by some Page Lifecycle that injects code and markup into your page without you even knowing it.
So What Is My Point
Both these examples are two high profile sites. They are from two very competent technology companies — however, one looks a little less skilled to the other – at least from a web development perspective. It seems to me that extra time and effort should have been placed by the Microsoft developers to trim out all the fat and make it as web friendly as possible.
I might be nit-picking at the HTML output but I do think its relevant. That code – even if it is compressed – is the final rendered output from a WebForms page. As soon as the page opens there is immediately markup errors, unmatched tags, extra body elements. It’s clearly not the best it can be. I’m not trying to make Microsoft look bad either – personally, I want to work for them some day, but the point is that in order to improve then you must first be honest with yourself and those around you.
WebForms are a powerful tool – don’t get me wrong – but it seems to me that they have abstracted web development too far. I always thought it was really cool about .NET the way you could go from web, desktop, console, mobile or whatever development you wanted to and it was still like second nature! It allowed you to focus on solving problems and less on how each area was supposed to work.
I’m not saying people can’t develop great applications with WebForms. In fact I still use them from time to time when I need to hack out a quick application that only the internal eyes of my company are going to see. However, when I’m browsing the web and come across a website that is packing a 50K ViewState or is littered with wasteful, pointless 40 character long ids, I just can’t help but feel that WebForms is starting to hurt the web a little.
That’s why I recommend that if you haven’t already, go try out ASP.NET MVC. It doesn’t take long to break away from WebForms and you’ll probably feel more comfortable within a few days.
Keep Your Website Alive (Don’t Let IIS Recycle Your Website)!
Have you ever opened a page for one of your websites and it lags for awhile before it finally shows a page but then all of your following requests are quick? If you were to look up the problem you’d find that often it ends up having to do with IIS meeting an idle time limit and shuts down your site. There is even some software you can purchase to fix the problem for you.
But who wants to spend money on something like that? Especially when we can solve this ourselves — even for Hosted Environments!
Stayin’ Alive — (ack! bad pun again!)
If you happened to check out that software above then you can probably glean what it does just from the title. I’d rather not devote my personal machine to something like that so lets see if we can’t approach this from an alternative route.
private static void _SetupRefreshJob() {
//remove a previous job
Action remove = HttpContext.Current.Cache["Refresh"] as Action;
if (remove is Action) {
HttpContext.Current.Cache.Remove("Refresh");
remove.EndInvoke(null);
}
//get the worker
Action work = () => {
while (true) {
Thread.Sleep(60000);
//TODO: Refresh Code (Explained in a moment)
}
};
work.BeginInvoke(null, null);
//add this job to the cache
HttpContext.Current.Cache.Add(
"Refresh",
work,
null,
Cache.NoAbsoluteExpiration,
Cache.NoSlidingExpiration,
CacheItemPriority.Normal,
(s, o, r) => { _SetupRefreshJob(); }
);
}
If we place this bit of code in the Global.asax and call it when Application_Start() is raised, we can basically start a job that keeps our website alive. You could just as easily use a Thread to host the refresh method but for this example we simply used an Action delegate (but if you are using an earlier version of .NET then you might HAVE to use a Thread to do this).
Once our application starts the refresh job is also started and is saved to the cache. In this example we’re using 60 seconds, but you can change this to be as often as you like.
So How Can We Keep It Fresh?
So how about an example of some code we can use? Here is a simple example that could keep our website alive. Replace the //TODO: in the example above with something like the following.
WebClient refresh = new WebClient();
try {
refresh.UploadString("http://www.website.com/", string.Empty);
}
catch (Exception ex) {
//snip...
}
finally {
refresh.Dispose();
}
This snippet uses a WebClient to actually make an HTTP call to our website, thus keeping the site alive! We could do any number of things from this code like updating local data or get information from external resource. This can be used to keep our site alive and our content refreshed, even if we’re using a Hosted Environment!
It is worth nothing that might not actually need to do an HTTP call back to your website. It is possible that using any method will keep your website from being killed off (but I haven’t tested it yet so let me know what happens if you try it). This example, however, has been tested and works quite well with my provider.

