Tuesday, June 3, 2008

Perfect ASP.NET application, Part 6

Objects, objects everywhere

ASP.NET is a great framework. It turns HTML into objects and it's so much easier to work with objects. I love working with objects. But sometimes it kills me that to do small thing you would need to create an object. Let say you need to show current date/time on a bottom of each page. You have 2 options. 

  1. Create asp:Label control, drop it on master page (I hope you use one in each of your project). In your OnLoad even you write following line lblDate.Text = clsGlobal.GetDateTime(DateTime.Now);
  2. Another option is simply write in a bottom of your master page <%=clsGlobal.GetDateTime(DateTime.Now)%>

Which option would you choose?

First of all why would you want to show current Date/Time on a page. It's simple. We live in a world where Google and Yahoo are kings. Every site owner is worried about how often spiders spider their precious websites. Look at this page. It's a google's cache of the www.mspiercing.com. Scroll to the bottom and you will see a date there. Now you know when Google's robot visited this page last time. 

Now I hope you made up your mind. I would chose #2. Simply because I hate to create small objects without any intelligence in it. It's simply a waste of memory and CPU resource.


Another problem, a lot of people want to do website branding or use themes. Meaning that they want to show for one person everything blue, for another person everything white, or change the logo of the site depending on who is logged in. How can we do it easily?

I offer relatively simple solution. What if we could write our HTML using following construction. <img src="@ImageFolder@/logo.gif> and had a component that would analyze our output stream and substitute @ImageFolder@ appropriately. I offer you a "Replacer". 

Response.Filter allows us to write such thing easily. First let's make a CConfig class which is a global Hashtable for our website and then CReplacer which is a class that being created for each request.

So idea would be that when our application starts we populate CConfig class and put it in clsGlobal

public class clsGlobal
{
    ......
    public CConfig replacer = new CConfig();
    public static void Init()
    {
        .......
        cfg.AddToken("SITENAME", "My Site");
    }
}

Change our clsStandardPage a little:

public class clsStandardPage : System.Web.UI.Page
{
    ......
    Replacer.CReplacer rpl = clsGlobal.replacer.GetReplacer(Response.Filter);
    Response.Filter = rpl;
    rpl.AddToken("DATE", DateTime.Now.ToString());
    rpl.AddToken("ImageFolder", "/brand1/images/");
}

And we done. Now look at this page

<HTML>
<BODY>
Welcome to @SITENAME@
Current date is @DATE@ and our logo is <img src="@ImageFolder@/logo.gif">
</BODY>
</HTML>

No objects created. The code does not break our HTML. The person who has no idea about programming languages can now look at it and understand. 

There are many uses for "Replacer". The most common  one is in CMS (Content Management System). Look at this page http://www.mspiercing.com/Product/razor-navel-ring-1370.aspx. Notice page Title matches the item's name, Item has a description, picture...... All that, I did with a "Replacer". The code  determines Title, Description, Image, BigImage, price.... and adds those as tokens to "Replacer". The SEO (search engine optimizator) can now move staff around at will. If he dumps on a page <img src="@Bigimage@"> user will see big image instead of regular image. He wants to make price red.... I do not care. He edits HTML so it becomes <font color=red>@PRICE@</font>

I hope you got an idea.

Note: You will be able to download Replacer from my last post. It will be included in a sample application.
Note: To improve runtime I made "Replacer" to run in unsafe mode. Meaning that you need to compile your .NET application with /unsafe flag. Easy to do. Dump following line in web.confiig

<system.codedom>
    <compilers>
        <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" compilerOptions="/unsafe" warningLevel="1"/>
    </compilers>
</system.codedom>

If you are on shared hosting environment most likely you will not be able to use /unsafe switch. Then you need to get your hands dirty and make small modifications. 

Note: To avoid problems with emails "Replacer" only counts 20 characters after it encounters first @ symbol. And if no second @ symbol it leaves the HTML intact. So HTML like this "my email is email@email.com send me all spam in a world" will not be modified.

Of course Replacer scans the whole HTML output. So you might think there is a performance hit. CPU is designed to do scans and comparing to creating and initializing several Label controls on your page it would be nothing. Also do you know that your IIS supports so called "HTML includes". It's constructions like this in HTML <!--#include virtual="insertthisfile.html" -->. How do you think it's working. The same scanning looking for <!-- #include.... And I do not remember anyone complaining.... Of course if you work in google you might have to come up with something else.

 

 

Continue >>

No comments: