Typed Convert using Generics

Last night I answerd a interesting question on the Asp.Net Forums that I thought is worth a post. The objective was to create a method using Generics that could get a value from the Session only instead of returning a Object it would return the value in the type defined in the generic method. Just to make the demonstration easier I'll use a Dictionary instead of the Session but it works just the same:

class TypeTest
{
    private static Dictionary<string, object> PretendSession = new Dictionary<string, object>();

    public static void Test()
    {
        PretendSession.Add("int", 10M);
        Console.Out.WriteLine(Get<int>("int"));
    }

    public static T Get<T>(string theKey)
    {
        object aSessionObject = PretendSession[theKey];

        if (aSessionObject == null)
        {
            return default(T);
        }

        return (T) aSessionObject;
    }
}

This code works well for most cases but you can get in trouble when you work with Value Types. Look at code that follows and to undestand the problems with boxing and unboxing value types:

 //doesn't work, need explicit cast 
int i = 10M; 

//now it's fine 
int i = (int)10M; 

//boxing and unboxing work fine 
object o = 10; 
int i = (int)o; 

//doesn't work 
object o = 10M; 
int i = (int)o;

When you know exactaly what is the type of you are putting inside the Session it all goes fine. When you don't know what type you are working with you need the help of the Convert class to convert the type before casting it. To do this we test if the object is of type ValueType and if it is, before casting it we use the ChangeType method of the Convert class to make sure that the object really contains the type we will try to cast it to.

 

class TypeTest
{
    static Dictionary<string, object> PretendSession = new Dictionary<string, object>();

    public static void Test()
    {
        PretendSession.Add("int", 10M);
        Console.Out.WriteLine(Get<int>("int"));
    }

    public static T Get<T>(string theKey)
    {
        object aSessionObject = PretendSession[theKey];

        if (aSessionObject == null)
        {
            return default(T);
        }

        if (aSessionObject is ValueType)
        {
            return (T)Convert.ChangeType(aSessionObject, typeof(T));
        }

        return (T)aSessionObject;
    }
}

Now you should be safe to use your Get<T> method. Hope this can help other people that face this same issue.

Passed 70-547

Hey, I'm just writing to let my friend know that I have passed the 70-547 exam and now I'm an MCPD Web Developer.

I have to say that the test was way easier than I thought. I think it was the easiest Microsoft test I have ever taken.

If you are asking why I still took a .NET 2.0 exam the reason is simple. I had already bought all the books last year. I was supposed to take the test last October but I had to help out at work doing some long shifts to deliver a product that was sold before we expected. Go news for them and a lot of work for me :-). Not to worry I really like the guys I work for and the system is kind of a son to me so I also had fun. Now that it's over I'm back to my plans.

Now I'm in the process of getting my MCT (Microsoft Certified Trainer).

I'll keep you guys posted on how it goes.

ELMAH: Error logging doesn't get any simpler

ELMAH stands for Error Logging Modules and Handlers. I don't love the name but everything else about it is great!! In it's site it is described as:

"ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment."

I'm using this blog as I write it and if I had to classify it I'd say it is a pre pre alpha release not suitable for anyone else but me. The only use I see for other people right now is to look around the code (what should be quick). Given my choice to put the application online in this early stage it seamed pretty obvious that that I needed to start logging the errors my users are getting so that I can work on them as soon as possible. As usual I was deciding between using NLog or Log4Net when I saw a new post by Scott Hanselman talking about ELMAH.

As usual Scott's post saved me a lot of time! Setting up ELMAH was really as simple as he said. In a matter of minutes I was logging all errors in my application. Now I can sleep well knowing that every weekend I'll have a list of errors to work on :-)

I highly recommend you use this in your application even if you are already using another logging framework. The cool thing about ELMAH is that if you missed something forgot to place logging on some part of your app, ELMAH won't. It will log every error you have and store it in XML, SQLServer, Oracle...

Lessons Learned in Url Rewriting

When I decided to write my own blog and leave Mephisto one of the few requirements I felt were really important was to maintain the url pattern I was already using. My articles had url's like this:

www.gbogea.com/year/month/day/permalink

When I first looked up url rewriting in google I found a great article by ScottGu that really suited my needs. I'm using IIS7 on my develpment machine and I thought I was also using it on the hosting service I contracted. ScottGu's post shows a really simple way to do rewriting when using IIS7. All you need is the UrlRewriter.Net module and a few configurations to your web.config.
Checkout SocottGu's post for the whole config, here I'll only show you the pattern I needed to be compatible with the articles url in Mephisto. Here it is:

<rewrite url="~/((19|20)\d\d)/(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])/(.+)" to="~/PostDetail.aspx?year=$1&amp;month=$3&amp;day=$4&amp;permalink=$5"/>

Once I did this everything worked fine. I had achieved my objective, or so I thought. The problem is that I found out later on that my hosting service was actually using IIS6 and to my sadness IIS6 doesn't do well with url's that do not have an extension.

When I contacted my hosting they informed me that they had support for ISAPI Rewrite, which is alson discussed in Scott's post but sadly not in engough depth for my case. The configuration is also a lot more anoying then with UrlRewrite.Net. If you have to use ISAPI Rewrite my first recomendation is to get in touch with your hosting and find out if they have version 2 or 3 installed. It makes a great difference. In my case I had version 3 installed. Here are the steps I took to configure it:

1 - Create a ".htaccess" file in the root or your web application.

2 - In the file I've written the following code:

RewriteEngine on
RewriteBase /
RewriteRule ((19|20)\d\d)/(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])/(.+)$ /PostDetail.aspx?year=$1&month=$3&day=$4&permalink=$5 [NC,L]


The rewrite rule is basically translating the pattern I'm using (www.gbogea.com/year/month/day/permalink) to the real pattern that the ASP.NET applcation understands (PostDetail.aspx?year=YYYY&month=MM&day=DD&permalink=WHATERVER).

The options and the end are also very important. NC means Case Insensitive. L means that no other subsquent rule should be processed, it stops here. You will find a lot of examples that use an R (which means Redirect) however this was not suited to my case. The redirect would be done to the new URL and then the url shown in the browser would be the ASP.NET url and not mine.

This usage was not easy to figure out. If you need any assistance on using ISAPIRewrite I can recomend this two links:

Documentation: http://www.helicontech.com/isapi_rewrite/doc/
Blog: http://helicontech.blogspot.com/search/label/isapi_rewrite

Helicon's blog was the one that helped me the most. The have a post about common issues people have which is really to the point.

Looking back at all the work I had it would probably be cheaper just to have my hosting plan upgraded to IIS7 but where would be the fun in that right? Joking aside, it's this kind of thing that make you learn, perhaps your client doesn't have the option to migrate to IIS7, then what would you do? Having said that, if you have the choice between using IIS 6 and 7 I would definitely go with 7 and avoid using ISAPI Rewrite altogether.

If you want to have a closer look at my web.config or the .htaccess file you can look at the source code for this blog at speakoutblog.codeplex.com. At this time there is no realease version yet but you can go to the source code and download any commit you want.