Storage usage stats by SpaceSniffer

Standard

If you are an engineer like myself, you end up accumulating tools that make your working life easier over the cause of  the years. Yesterday, I spend sometime cleaning up my laptop and was shocked to discover the amounts of tools I have accumulated in my toolbox so I thought it would be great to blog about these tools for they might be useful to someone as well.

We all clean our computing machine (laptop, desktop etc) once in a while and sometime you like to know which folder/program is taking up space. There are a few tools to sniff out the space consumption on your machine but I have see or used any better than SpaceSniffer. SpaceSniffer cruises through your machine in a few min and shows a graphical representation of your space usage. The good guys at Uderzo Software have been kind enough to give this away for free so click the link above and get sniffing.

Credit: Featured  image by nordhell at Odosketch.com.

Conditional Validation in ASP.NET MVC – RangeIf

Standard

Simon Ince made a great post about conditional validation in mvc which he extended in his post conditional validation in asp.net mvc 3. Asp.net mvc validation is one of asp.net mvc’s great extensible points . The framework comes with a decent amount of validations attribute such as range, stringlength etc but sometimes we find ourselves wanting to perform a specify type of validation that the framework doesn’t support and conditional validation is a perfectly good example. This is one of those validation types that most people feel the asp.net mvc team should have included in the framework but hey, they cannot do it all,¬† so we look to ourselves and to good people like Simon to the rescue.

Simon goes into details on how to create a RequiredIf validation so I wont elaborate on that (just dive into the links above for info on RequiredIf validation). In using Simon Requiredif validation, I decided its would be great to build on it to be applicable to other rules like Rangeif, StringLenghtIf, etc, starting with RangeIf. The first thing I needed to do was define the signature of the validation attribute. To keep things consistent with Simon’s, I decided to go with the signature as follows for an age property on the person class-

[RangeIf(11, 25, "IsUKResident", false, ErrorMessage = "If you are not a UK  resident, your age has to be between 11 and 25")]

The next thing to do was to define the RangIf attribute class below , inheriting from RangAttribute
public class RangeIfAttribute : RangeAttribute , IClientValidatable
{
public string DependentProperty { get; set; }
public object TargetValue { get; set; }

public RangeIfAttribute(int minimum, int maximum, string dependentProperty

, object targetValue): base(minimum, maximum)
{
this.DependentProperty = dependentProperty;
this.TargetValue = targetValue;
}

protected override ValidationResult IsValid(object value,

ValidationContext validationContext)
{
// get a reference to the property this validation depends upon
var containerType = validationContext.ObjectInstance.GetType();
var field = containerType.GetProperty(this.DependentProperty);

if (field != null)
{
// get the value of the dependent property
var dependentvalue = field.GetValue(validationContext.ObjectInstance, null);

// compare the value against the target value
if ((dependentvalue == null && this.TargetValue == null) ||
(dependentvalue != null && dependentvalue.Equals(this.TargetValue)))
{
// match => means we should try validating this field
if (!base.IsValid(value))
// validation failed - return an error
return new ValidationResult(this.ErrorMessage, new[]

{ validationContext.MemberName });
}
}

return ValidationResult.Success;
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules

(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule()
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "propertydependencyrule",
};

string depProp = BuildDependentPropertyId(metadata, context as ViewContext);
string targetValue = (this.TargetValue ?? "").ToString();
if (this.TargetValue.GetType() == typeof(bool))
targetValue = targetValue.ToLower();

 

rule.ValidationParameters.Add("dependentproperty", depProp);
rule.ValidationParameters.Add("targetvalue", targetValue);
rule.ValidationParameters.Add("rule", "range");
rule.ValidationParameters.Add("ruleparam","["+Minimum+","+Maximum+"]");

yield return rule;
}

 

private string BuildDependentPropertyId(ModelMetadata metadata,

ViewContext viewContext)
{
// build the ID of the property
string depProp = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldId

(this.DependentProperty);
// unfortunately this will have the name of the current field appended to the beginning,
// because the TemplateInfo's context has had this fieldname appended to it. Instead, we
// want to get the context as though it was one level higher (i.e. outside the current property,
// which is the containing object (our Person), and hence the same level as the dependent property.
var thisField = metadata.PropertyName + "_";
if (depProp.StartsWith(thisField))
// strip it off again
depProp = depProp.Substring(thisField.Length);
return depProp;
}
}

The code above is self explanatory so I wont elaborate. Note that we pass on the client rule and its parameters through rule.ValidationParameters in the GetClientValidationRules method. The next thing to do was create my client script (unobtrusive adapter) below
$.validator.addMethod('propertydependencyrule',
function (value, element, parameters) {
var id = '#' + parameters['dependentproperty'];

// get the target value (as a string,
// as that's what actual value will be)
var targetvalue = parameters['targetvalue'];
targetvalue =
(targetvalue == null ? '' : targetvalue).toString();

// get the actual value of the target control
// note - this probably needs to cater for more
// control types, e.g. radios
var control = $(id);
var controltype = control.attr('type');
var actualvalue = "";

switch(controltype)
{
case 'checkbox' :
actualvalue = control.attr('checked').toString(); break;
case 'select' :
actualvalue = $('option:selected',control).text(); break;
default:
actualvalue = control.val(); break;
}

// if the condition is true, reuse the existing
// required field validator functionality
var rule = parameters['rule']
var ruleparam = parameters['ruleparam']
if (targetvalue === actualvalue)
return $.validator.methods[rule].call(
this, value, element, ruleparam);

return true;
}
);

$.validator.unobtrusive.adapters.add(
'propertydependencyrule',
['dependentproperty', 'targetvalue', 'rule', 'ruleparam'],
function (options) {

 

options.rules['propertydependencyrule'] = {
dependentproperty: options.params['dependentproperty'],
targetvalue: options.params['targetvalue'],
rule: options.params['rule'],
ruleparam: eval(options.params['ruleparam']),
};
options.messages['propertydependencyrule'] = options.message;
});

That’s it. We now have our RangeIf validation attribute. Notice I modified Simon’s client side code to a generic propertydependencyrule so you can use propertydependencyrule for other propertydependency validation attributes like StringLenghtIf by passing along the max jquery.validator¬† rule and its parameters. In my next post, I will extend this to RegularExpressionIf, StringLenghtIf, and more. Stay tuned.

A reminder of why I dislike asp.net webforms

Standard

A few hours ago, I stumbled on asp.net mvp –¬†an up and coming asp.net opensource framework¬†who’s aim¬†to¬†to unit the productivity of asp.net webforms¬† and the exensibilty of asp.net mvc. After combing through the links and the how-to’s on http://aspnetmvp.com , I had warmed up to the idea and was willing to give it a try in the new furture. This post should probably be titled asp.net mvp but¬†the blog post(http://www.aaron-powell.com/yes-i-like-webforms)¬†in relation to asp.net mvp in¬†support of asp.net webforms got my heart going so I decided to respond with this post. If you have head it all, please skip this post else you are welcome to read on.

The blog post(http://www.aaron-powell.com/yes-i-like-webforms) in support of asp.net webforms list some very interesting point that I strongly support especially in relation to viewstate. People who complain about veiwstate just don’t know how to use it and its a fact. I actually agree with everything except for his argument¬†quoted below¬†in support of asp.net webform controls.

Controls are great, they package up some functionality and make it easy to redistribute. But people often say that this is one of the big downsides of WebForms and MVC gives you much better flexibility. But think about some of the trivial (read: boring) tasks which we have to do as developers:

  • Create a login form
  • Output a collection of data using a template

So with MVC this is something that you end up having to write yourself, sure there are some helpers like Html.EditorFor and stuff so you can quickly display something. And it’s true there’s plenty of good extensions to do things like Repeaters, so this is just taking WebForms concept into MVC right?

One of the other main criticisms of controls is that they generate HTML for you that is hard to style, and often unchangable. But think about what they are trying to generate, a standard design cross-browser. Try having a floating layout which can be dropped anywhere and look the same?

True it makes them less flexible, but it depends what you’re trying to achieve

Sure, controls are great because they allow us to componentize and reuse functionalities but¬†with a greater sacrifice. If you just want to get up and going looking like ooh say anything else but precise, webform controls will do it well. Webforms are great in its composition architecture and since its been around for a while (.net world), its proven itself with a ton of best practices and guidlines. On the other hand, I(I spoke for myself and only myself)¬†dislike it because it tends to create what i call “robot developers”. Run an http test against a decent webform dev and you will actual find out what he knows about the underlying technology. Sure, they dont “need” to know it because they just have to drag and drop control but… you(assuming you agree)¬†and i know that in order to build great application, you almost have to go beyond drag&drop and property setting. Another issues I have with webforms is¬†the inability to¬†control the html rended by the controls.¬†The author asserts that its hard to¬†stay compliant¬†with the statement- “One of the other main criticisms of controls is that they generate HTML for you that is hard to style, and often unchangable. But think about what they are trying to generate, a standard design cross-browser. Try having a floating layout which can be dropped anywhere and look the same?”, but that’s only useful, again, to the “robot develper” because instead of learning how to do it using the right technology(thml,css,js), they end up relying on the control to do it. To add to injury, even though they are designed to generate standard cross-browser html ,they don’t. There are too many browsers to think your webform control will work flawlessly in everyone of them. In conclusion, controls in asp.net webforms hurts the framework to some extent. I will¬†advocate controles but only when the engineer has the ability to make modification when need be. That’s why I love asp.net mvc. It takes sometime to get up to speed and yes it has its own problem but in the end, I believe as a designer/developer, asp.net mvc¬† is more rewarding that asp.net webforms.¬† Hopefully, asp.net mvp will bring these two together.

 

Credits: Post image by ksomero at odosketch.com

ASP.NET MVC Action & Reaction

Standard

If you are familiar with ASP.NET MVC, you are probably familiar with the State Validation mechanism that was shipped starting from v1. Its a great way to validate your model and funnel your validation result to the user if need be. What I find lucky or I should probably say what I thought was lucking was the fact that it only dealt with error. There is nothing wrong with there and it probably the sole intention but I wanted something general. For every event the user executes (action), they expect a reaction. The most common reaction is page reload with content in relation to the user action. With that in mind, I created an Html helper  provide a generic reaction to the user, based on their action. It could be errors, it could be a warning or a successful message. These are thing developers do very often. Below is the code for my Html helper. Please not this is was a quick hack to get it working. I will post my updated to the helper when I make the final changes.

So here is how it works. All my views are strongly typed and accepts a ViewModel type. My ViewModels inherits from a base ViewModel class which provide the implementation for adding ActionMessage’s to the view. As seen below, my ContactViewModel inherits from the ViewModel abstract base class.

public enum ActionMessaeType {
    Success = 1,
    Failure = 2,
    Warning = 3,
    Alert = 4
}

public class ActionMessage {

    public ActionMessaeType MessageType
    {
        get;
        set;
    }

    public string Message
    {
        get;
        set;
    }

    public string ForAction
    {
        get;
        set;
    }

    public ActionMessage(ActionMessaeType messagetype,
                   string message)
    {
        MessageType = messagetype;
        Message = message;
        ForAction = string.Empty;
    }

    public ActionMessage(ActionMessaeType messagetype,
                string message, string foraction)
    {
        MessageType = messagetype;
        Message = message;
        ForAction = foraction;
    }
}

public abstract class ViewModel {
    private List<ActionMessage> _internalactionmessages
                            = new List<ActionMessage>();
    public List<ActionMessage> ActionMessages
    {
        get { return _internalactionmessages; }
    }
    public ViewModel(){}
    public ViewModel Add(ActionMessage actionmessage)
    {
        _internalactionmessages.Add(actionmessage);
        return this;
    }
    public ViewModel Remove(ActionMessage actionmessage)
    {
        _internalactionmessages.Remove(actionmessage);
        return this;
    }
    public ViewModel Clear()
    {
        _internalactionmessages.Clear();
        return this;
    }
}

public class ContactViewModel : ViewModel {
    public Contact Contact
    {
        get;
        set;
    }
}

 

My Contact View take accepts a ContactViewModel. Here is my page tag in my Contact.aspx

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.
Master" Inherits="System.Web.Mvc.ViewPage<YourNameSpace.
Models.ViewModel.ContactViewModel>" %>

 

Below is the post Contact Action method in my Controller

Code Snippet
  1. [HttpPost] //Post
  2. ¬†¬†¬†¬†¬†¬†¬†¬†public ActionResult Contact([Bind(Exclude = “Id”)]Contact contact)
  3.         {
  4.             //if maodel is not valid, send validated contact
  5.             if (!ModelState.IsValid)
  6.             {
  7.                 return View(new ContactViewModel { Contact = new Contact() }
  8. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†.Add(new ActionMessage(ActionMessaeType.Failure, “Please correct the errors in the highlighted below and try again”, “create-contact-failure”)) as ContactViewModel);
  9.             }
  10. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†//save contact here……
  11.             //Clear ModelState or redirect
  12.             ModelState.Clear();
  13.             //display view with action message
  14.             return View(new ContactViewModel { Contact = new Contact() }
  15. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†.Add(new ActionMessage(ActionMessaeType.Success, “Thank you for your message. We will get back to you as soon as possible if a response is need.”, “create-contact-success”)) as ContactViewModel);
  16.         }

 

You will notice from the code above that based on the certain events during the action execution, I add an ActionMessage to the ViewModel before its passed on to the view. The ActionMessage take a messagetype (failure, success, alert,‚Ķ), a message to be displayed and a ‚Äúforaction‚ÄĚ parameter which depicts where the message should show in the view.

When the¬† view is rendering, the html helper is called to display the action messages. The helper can take a ‚Äúforaction‚ÄĚ parameter which is used to determine which ActionMessages to show. If no ‚Äúforaction‚ÄĚ is passed, all messages are displayed. Here is the code for the Helper method

Code Snippet
  1. public static class ActionMessageExtension
  2.     {
  3. ¬†¬†¬†¬†¬†¬†¬†¬†public static readonly string ActionMessageCssClassName = “action-message”;
  4.         public static string getActionMessageCssClassName(ActionMessaeType messagetype)
  5.         {
  6.             switch (messagetype)
  7.             {
  8. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†case ActionMessaeType.Success: return “action-message-success”;
  9. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†case ActionMessaeType.Alert: return “action-message-alert”;
  10. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†case ActionMessaeType.Failure: return “action-message-failure”;
  11. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†default: return “action-success-warning”;
  12.             }
  13.         }
  14.         public static string ActionMessage(this HtmlHelper htmlHelper)
  15.         {
  16.             return ActionMessage(htmlHelper, string.Empty /* message */);
  17.         }
  18.         public static string ActionMessage(this HtmlHelper htmlHelper, List<ActionMessage> messages)
  19.         {
  20.             return ActionMessage(htmlHelper, messages, string.Empty /* htmlAttributes */);
  21.         }
  22.         public static string ActionMessage(this HtmlHelper htmlHelper, string foraction)
  23.         {
  24.             return ActionMessage(htmlHelper, null /*messages*/, foraction, (object)null /* htmlAttributes */);
  25.         }
  26.         public static string ActionMessage(this HtmlHelper htmlHelper, List<ActionMessage> messages,string foraction)
  27.         {
  28.             return ActionMessage(htmlHelper, messages,foraction, (object)null /* htmlAttributes */);
  29.         }
  30.         public static string ActionMessage(this HtmlHelper htmlHelper, List<ActionMessage> messages, string foraction, object htmlAttributes)
  31.         {
  32.             return ActionMessage(htmlHelper, messages, foraction, new RouteValueDictionary(htmlAttributes));
  33.         }
  34.         public static string ActionMessage(this HtmlHelper htmlHelper, List<ActionMessage> messages, string foraction, IDictionary<string, object> htmlAttributes)
  35.         {
  36.             //if no messages are passed in, the viewdata model is checked for messages to display
  37.             if (messages == null)
  38.                 messages = (htmlHelper.ViewData.Model as ViewModel).ActionMessages;
  39.             else //merge parameter with view actionmessages
  40.                 messages.AddRange((htmlHelper.ViewData.Model as ViewModel).ActionMessages);
  41.             if (messages == null) return null;
  42.             if (!(messages.Count > 0)) return null;
  43.             if (foraction != null)
  44.                messages = messages.FindAll(delegate(ActionMessage actmgs) {return actmgs.ForAction == foraction; });
  45.             if (messages == null || !(messages.Count > 0)) return null;
  46.             StringBuilder result = new StringBuilder();
  47.             //Render Success Messages
  48.             RenderActionMessage(messages, ActionMessaeType.Success, foraction, htmlAttributes,ref result);
  49.             //Render Alert Messages
  50.             RenderActionMessage(messages, ActionMessaeType.Failure, foraction, htmlAttributes, ref result);
  51.             //Render Alert Messages
  52.             RenderActionMessage(messages, ActionMessaeType.Alert, foraction, htmlAttributes, ref result);
  53.             //Render Warning Messages
  54.             RenderActionMessage(messages, ActionMessaeType.Warning, foraction, htmlAttributes, ref result);
  55. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†//Render …..more types of messages
  56.             return result.ToString();
  57.         }
  58.         private static void RenderActionMessage(List<ActionMessage> messages, ActionMessaeType messagetype, string foraction, IDictionary<string, object> htmlAttributes,ref StringBuilder htmlresults)
  59.         {
  60.             StringBuilder htmlSummary = new StringBuilder();
  61.             //Render  Messages
  62.             List<ActionMessage> typemessages = messages.FindAll(delegate(ActionMessage actmgs) { return (actmgs.MessageType == messagetype && actmgs.ForAction == foraction); });
  63.             if (typemessages.Count > 0)
  64.             {
  65. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†TagBuilder messageList = new TagBuilder(“ul”);
  66.                 messageList.MergeAttributes(htmlAttributes);
  67. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†messageList.MergeAttribute(“class”, getActionMessageCssClassName(messagetype));
  68.                 foreach (ActionMessage message in typemessages)
  69.                 {
  70.                     if (!String.IsNullOrEmpty(message.Message))
  71.                     {
  72. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†TagBuilder listItem = new TagBuilder(“li”);
  73.                         listItem.SetInnerText(message.Message);
  74. ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†listItem.MergeAttribute(“class”, ActionMessageExtension.ActionMessageCssClassName);
  75.                         htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal));
  76.                     }
  77.                 }
  78.                 messageList.InnerHtml = htmlSummary.ToString();
  79.                 htmlresults.Append(messageList.ToString(TagRenderMode.Normal));
  80.             }
  81.         }
  82.     }

And here is how its used in the Contact.aspx view.

<%=Html.ActionMessage("create-contact-failure") %>

 

I hope this help. I’m having a hard time finding a good code plug in for Live Writer as I am not so pleased with how the code is presented above. When I do find a good one, I will update the code section of the post.

Future

Like i said, this was just a hack. The best way will be to have the Message Collection as a property of the ViewData since it cannot be used in its current state without using a strongly typed view who’s Model inherits from the base ViewModel class. That’s using Injection of some sort to update the ViewData used in the Views. I also want to pipe all the validation errors for the ModelState through the ActionMessage helper so I can use that as an all purpose notification mechanism.

If you have any suggestions, please let me know.

Timestamp issue with MySql connector 6.0 – 6.1 for Entity Framework

Standard

This is really a short post as to highlight an issue that I run into (and most will) when using MySql with Entity Framework employing the mysql connector net.

 

Scenario

I work mostly on my laptop which has mysql connector 6.0.4 installed. Using the connector in conjunction with EF v1 generated my domain object with timestamp fields mapping from a binary in my conceptual schema to timestamp in my physical schema.  Everything worked just fine till I deployed to my production machine and realized I didn’t have mysql connector installed on my production server. So…I did what most will do, download the connect but installed the latest version (v6.1). After deploying my app to the server, the unexpected happened. My app was broken. The error message indicated that Edm.binary was not compatible to mysql.timestamp. OK, I was stumped. The app works just fine on my my laptop why not on my server.

 

Solution

After a couple of hours using process of elimination, I realized that using version 6.1 of the connector sets your mapping for timestamp from Edm.DateTimeOffset(conceptual schema) to timestamp (physical schema)which worked fine but version 6.0.4 of the connector sets your mapping for timestamp from Edm.binary(conceptual schema) to timestamp (physical schema) which also works as well. DateTimeOffset is a type specific to Sql server so the best option for me was to stay with 6.0.1  (using binary) which is generic and can be used with other db’s if ever need.

Adventures to my dream part 1

Standard

I have been hosting most of my personal application from my home pc for a while until charter blocked port 80 and others. This prevented me from doing exactly that. Disappointed in Charter, I switched to  AT&T U-verse for a better service. That worked great for a couple of week and then ‚Ķ..boom, my ports got jammed again. I called U-verse support to help resolve this but they claim they aren‚Äôt blocking any ports. Between you and I, I think they are even though DynamicDNS says the ports are open. Long story short, I decided it was time to shell out some cash for a dedicated windows 2008 server, so I did. I‚Äôm actually very happy with my server. I configured every aspect of it to the last bit but this blog is not really about how happy i am about my dedicated server but about my experience setting up my applications in IIS 7.

IIS 7 by far is the best IIS release ever. Built ground up from scratch to support mainly the modular architecture requested by so many web administrators. I have been very impressed and at the same time, frustrated. Why frustrated? Well it has its learning curve and without the IIS 7 documentation, I wont be any closer to understanding how IIS 7 works. So I have decided to make a blog post of any knowledge I can pass on to others in relation to configuring IIS

Today’s ‚ÄúDid you know‚ÄĚ:  IIS 7 allows you to run multiple sites on the same port each with a different host name. IIS using Host Names to differentiate between different sites and forwards the request to the site. Now, you can host all your sites on port 80 if you wont to so far as their host name are different. Example, say you have 2 sites. www.site1.com and www.site2.com. You can create two sites in IIS with host names ‚Äúsite1.com‚ÄĚ and ‚Äúsite2.com‚ÄĚ and both binding to port 80. A request to www.site1.com and www.site2.com respectively will be routed to site1.com and site2.com respectively. your request to be served by that sit

Today‚Äôs War wound: Setting up ftp in IIS 7 with the new ftp service is very easy and also support the same port binding mechanism explained above. Using the example above, say you extend both site with ftp publishing feature. You will think setting the host names for the ftp binds (same port 21)  should give you the same ability to ftp into www.site1.com and www.site2.com through ftp.site1.com and ftp.site2.com using the host name feature and the same port 21. Well, you can do that but you are in for a treat if you plan on connecting from any ftp client to those ftp site. It just fails. For some reason, the clients don‚Äôt quit know who to use host name in their request. The solution is not to use host names for ftp but rather different ports and leaving the host name to unassigned. Then connect to the different ftp sites using the servers ip and the different ports.

I hope this helps anyone in their quest to tame IIS 7.

We could use more spellcheckers

Standard

I have been very busy with work since I came back from Ghana so I have had¬† limited time to blog. But then again, that’s no excuse since I could post a line or two here and there with a hint of wisdom but …. So here I am back at it again. This time, it‚Äôs about spelling.¬† Here is the interesting part, the web is all about content. Anytime you open a browser to a site, you are slapped with many types of contents in different sizes. These include videos, sounds, pictures and lastly and most prominent of them all, text. In our daily work, we are either typing or reading. Both of which deals with text but ask me how many standalone spell checker tools one can employ and you will be amazed at how many there are. Very few I must say. I am still struck by the fact that visual studio does not ship with a spell checker out-of-the-box after 6 versions. Every thing from Windows form design to Web development involves publishing text content of some sort and yet, there isn’t a solid spell checker that comes with it. Instead, we have to resort to MS word , some other text editing tool (Openoffice etc) or plug-in etc. Frankly, every time I run into an interface design software that doesn’t have a spellchecker, I get dumbfounded. Is spell checking really the least most important feature or what. Then again, someone would say, what‚Äôs the big deal. If it bothers you so much, why not learn how to spell. Very true; I wont dispute the fact that we do need to know how to spell. After all, its one of the basic medium of communication since the invention of papyrus. But with the volume of content this generation produces daily, most people are bound to make spelling mistakes so why not help avoid it.¬† Matt Cutts (Head of Google web spam team) points out here as to how important spelling is on the web and how they can turn customers away. People don‚Äôt trust website with spelling mistakes. To that end, I know my ranting is not going to change the feature set of content publishing software’s like visual studio etc, so here are a couple of things you can do to keep your customers coming back.

1. Spell check your content in any good text editing tool like MS Office Word

2. Let a colleague or friend prove read your content for you. You can easily miss your mistakes even if you ready it more than you think you should. It came from you and you are bound to miss one or two.

3. If you can find a spellchecker plug-in to your content authoring software, plug it in and use the heck out of it.

4. For web developers, you can find online services that can scrawl your site for spelling mistakes. Beware of the service you choose; as Matt Cutts post suggests that you probably don’t want to use a service who‚Äôs own site has spelling mistakes.

I’m actually checking this post for wrong spelling using Windows live writer. Kudos to the windows live team for including a spell checker. With that said,  let me know what you think if you disagree with anything I have said or want to add to it.