Showing posts with label Search Engine Optimization. Show all posts
Showing posts with label Search Engine Optimization. Show all posts

Wednesday, September 8, 2010

Handling Head Section Dynamically

When it comes to Search Engine Optimization there are few modifications we need to do in Header Section. If a web application has simple structure then handling Head Section is an easy task. But consider an application like E-Commerce store where there is huge collection of different kind of products which belongs to various categories and sub categories. In that case we have to manipulate many things for every request depending on the product, its details, depending on category and subcategory. ( URL Rewriting is one the important thing for Search engine optimization, which I have already discussed in some articles, Article 1, Article 2).
Head section also plays an important role for Search Engine Optimization, in this article we will discuss all elements which matters in HEAD section and can be handled dynamically in asp.net.
  • Handling Page Title: Page title can contain many things explaining details or abstract about the Product or about the current page which is being displayed for some purpose. User might click on some link and page is being redirected to display some product or category. In that case Page Title should also be change accordingly. This can directly be handled as follow


    protected void Page_Load(object sender, EventArgs e)
        {
            this.Header.Title = "This is Demo Title";
            //we can also use following
            //Page.Header.Title or Page.Title or this.Title
            //Can also apply some switch case, depending on Query String.
            //depending on product or category details
        }
  • Adding JavaScript in Head Section: We can either load direct JavaScript in HEAD section or we can add JS file in HEAD Section. check out following codes


    protected void Page_Load(object sender, EventArgs e)
        {
            HtmlGenericControl HTMLControl = new HtmlGenericControl();
            HTMLControl.TagName = "script";
            HTMLControl.Attributes.Add("type", @"text\javascript");
            HTMLControl.InnerText = @"alert('Insert Your JavaScript as String HERE instead of this Alert')";
            this.Page.Header.Controls.Add(HTMLControl);
        }

    Also we can add JavaScript file reference as below.



    protected void Page_Load(object sender, EventArgs e)
        {
            HtmlGenericControl HTMLControl = new HtmlGenericControl();
            HTMLControl.TagName = "script";
            HTMLControl.Attributes.Add("type", @"text\javascript");
            HTMLControl.Attributes.Add("src", "yourJSFile.js");
            this.Page.Header.Controls.Add(HTMLControl);
       }
  • To add content Meta Type in HEAD Section we can use following code.


    protected virtual void AddMetaContentType()
    {
    HtmlMeta meta = new HtmlMeta();
    meta.HttpEquiv = "content-type";
    
    meta.Content = Response.ContentType + "; charset=" + Response.ContentEncoding.HeaderName;
    
    Page.Header.Controls.Add(meta);
    
    }
    
  • To Add Meta Section, e.g. For Keyword and Description we can use following function

    protected void AddMetaTag(string name, string value)
      {
       if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value))
        return;
    
       HtmlMeta meta = new HtmlMeta();
       meta.Name = name;
       meta.Content = value;
       Page.Header.Controls.Add(meta);
      }
    
Submit this story to DotNetKicks

Read more...

Monday, August 30, 2010

Url Rewriting Made Easy - Article 2

Before I explain what is URL Rewriting and how simple it is to go for, kindly ready my previous article on same topic i.e. Url Rewriting Made Easy - Article 1, in this article I have explained some basics about URL Rewriting.
The very obvious question rises is, why should you go for URL Rewriting?
Why Should I go For rewriting URL?
  • Short URLs
  • easy to type & easy to remember URLs
  • Site Structure is Visible through URLs
  • URLs are precise and which won't change
  • URLs WHICH MAKE SENSE for End USER as well as for SEO purpose
Now if we look at above points as a web developer then we are very sure that these all things prone to change, we need to pass parameters and change directory structure of the web application. If the web application is very huge then managing above things is a headache.
Lets discuss the case of online shopping; "As a developer for e-commerce application or for online super market projects"; as per above bullet points we need separate URL for followings
  • Every Product should be identified separately
  • Category as well as subcategory should have separate identity
  • Price Range wise
  • Miscellaneous
  • Etc...
Basically one should be able to maintain and manage URLs as per requirement and need.
Now there is a trick, we have to show one URL on browser and internally use different url. Yes we are showing something which is readable and easy; which satisfies all bullet points listed above, but internally we can manage our logic our way rather in traditional way... 
e.g. we are displaying url say "http://www.mysite.com/product1" and we can internally use url "http://www.mysite.com/default.aspx?category=product1" its quite logical.Now the ultimate question arises is how to achieve this? So lets start building the logic. Check out following diagram, it is a logical flow of URL Rewrite operation.


So the very important thing we need to rewrite url is HTTP handlers, but before developing this handler we need to decide what URLs we should build for web application. For this Demo Code we will develop URLs which will be either Datewise as well as Product Namewise or show all products. Lets Consider we have following URLs which internally redirects to Default.aspx page with query string.
  • http://www.yoursite.com/PRODUCTS.aspx
  • http://www.yoursite.com/2010.aspx
  • http://www.yoursite.com/2010/08.aspx
  • http://www.yoursite.com/2010/08/24.aspx
Above links will be internally redirect to Default page in respective order as
  • http://www.yoursite.com/default.aspx?products=allproducts
  • http://www.yoursite.com/dafault.aspx?year=2010
  • http://www.yoursite.com/dafault.aspx?year=2010&month=08
  • http://www.yoursite.com/default.aspx?date=2010-08-24
So Rewriting of URL gives us flexibility of having different URLs for different kind of query string, in above example we have four different URLs pointing toward same page. I think this is the beautiful part, search engines see four different, readable URLs but we can handle data in traditional way. (For easy Reference check out DemoCode)
This URL module is same as Article 1 but RewriteModule.cs file is added. Function of PostBack.Browsers is similar i.e. to maintain URL during postbacks.
Now we will develope Code for RewriteModule.cs, this class file implement IHttpModule interface, whose code is as below.
namespace Rewrite
{
    public class RewriteModule : IHttpModule
    {
        public RewriteModule()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        #region IHttpModule Members

        public void Dispose()
        {
            //  throw new NotImplementedException();
        }

        public void Init(HttpApplication context)
        {
            //   throw new NotImplementedException();
            context.BeginRequest += new EventHandler(RewriteModule_BeginRequest);

        }

        void RewriteModule_BeginRequest(object sender, EventArgs e)
        {
            // throw new NotImplementedException();
            HttpContext context = ((HttpApplication)sender).Context;
            string path = context.Request.Path.ToUpperInvariant();
            string url = context.Request.RawUrl.ToUpperInvariant();

            path = path.Replace(".ASPX.CS", "");
            url = url.Replace(".ASPX.CS", "");

            if (url.Contains("/PRODUCTS/"))
            {
                RewriteProduct(context);
            }
            else RewriteDefault(context);
        }

        #endregion

        private static readonly Regex YEAR = new Regex("/([0-9][0-9][0-9][0-9])", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        private static readonly Regex YEAR_MONTH = new Regex("/([0-9][0-9][0-9][0-9])/([0-1][0-9])", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        private static readonly Regex YEAR_MONTH_DAY = new Regex("/([0-9][0-9][0-9][0-9])/([0-1][0-9])/([0-3][0-9])", RegexOptions.IgnoreCase | RegexOptions.Compled);

        private void RewriteDefault(HttpContext context)
        {
            string url = context.Request.RawUrl;

            if (YEAR_MONTH_DAY.IsMatch(url))
            {
                Match match = YEAR_MONTH_DAY.Match(url);
                string year = match.Groups[1].Value;
                string month = match.Groups[2].Value;
                string day = match.Groups[3].Value;
                string date = year + "-" + month + "-" + day;
                context.RewritePath(@"~/default.aspx?date=" + date, false);
            }
            else if (YEAR_MONTH.IsMatch(url))
            {
                Match match = YEAR_MONTH.Match(url);
                string year = match.Groups[1].Value;
                string month = match.Groups[2].Value;
                string path = string.Format("default.aspx?year={0}&month={1}", year, month);
                context.RewritePath(@"~/" + path, false);
            }
            else if (YEAR.IsMatch(url))
            {
                Match match = YEAR.Match(url);
                string year = match.Groups[1].Value;
                string path = string.Format("default.aspx?year={0}", year);
                context.RewritePath(@"~/" + path, false);
            }
            else
            {
                context.RewritePath(url.Replace("Default.aspx", "default.aspx")); 
            }

        }

        private void RewriteProduct(HttpContext context)
        {
            string path = "default.aspx?products=allproducts";
            context.RewritePath(@"~/" + path, false);
        }
    }
}
Lets understand this code first. We have divided logic in two functions, one handles Dates using Regular Expression and other simple handles Product category. i.e. RewriteDefault and RewriteProduct functions. Both functions can be static. To rewrite URL we are using context.RewritePath function, and we have added one eventHandler for context.BeginRequest; i.e.RewriteModule_BeginRequest. Here I assume that the reader is aware about implementation of HTTPMODULE.
After this we will develop index.aspx page, which looks like following
HTML side of Index.aspx is as below
Please Refer HTML of index.aspx, due to limitation of HTML rendering and Blogger compatibility I am not able to display code here. (Please refer html of index.aspx, check demo code.)
index.aspx page uses four URLs discussed above and redirects it self Default.aspx. Now HTML of Default.aspx and Code Behind are as below
This is Default.aspx Page
Here you can see Messages

Code Behind is as below
protected void Page_Load(object sender, EventArgs e)
    {
        if (!string.IsNullOrEmpty(Request.QueryString["date"])) 
        {
            //Write your logic Instead of following code.
            message.InnerText = "Logic For fetching data as per Date: " + Request.QueryString["date"];
        }
        else if (!string.IsNullOrEmpty(Request.QueryString["year"]) && !string.IsNullOrEmpty(Request.QueryString["month"])) 
        {
            //Write your logic Instead of following code.
            message.InnerText = "Logic For fetching data as per Year and Month: " + Request.QueryString["year"] + "/" + Request.QueryString["month"];
        }
        else if (!string.IsNullOrEmpty(Request.QueryString["year"])) 
        {
            //Write your logic Instead of following code.
            message.InnerText = "Logic For fetching data as per Year: " + Request.QueryString["year"];
        }
        else if (!string.IsNullOrEmpty(Request.QueryString["products"])) 
        {
            //Write your logic Instead of following code.
            message.InnerText = "Logic For fetching data for all Products: " + Request.QueryString["products"];
        }
    }
In web.config file (as per HTTPMODULE implementation) we add following code


We are done with our rewrite url logic, for handling Postbacks check out the logic written in "HandlePostBacks.cs" and "PostBack.browser" files. This logic is already explained in Url Rewriting Made Easy - Article 1
Download Demo codes
Submit this story to DotNetKicks

Read more...

Sunday, August 22, 2010

Url Rewriting Made Easy - Article 1

Rewriting of URL is one of the Major point in terms of Search Engine Optimization as well as in terms of Readability and usability. 
We should go for rewriting of URL because of following reasons
  1. Search Engines Recognizes different URLs.
  2. Same Page can be executed with different unique URLs.
  3. We can also introduce our keywords in the URLs.
In this article we will discuss very preliminary way to generate unique URL which internally can target to same page. We will also discuss how to maintain the URL during postbacks. We have to consider postback case because though we manage to redirect to some URL which is rewritten, during postbacks it again changes to the actual URL.
 
In general Our URLs looks like below
http://www.yourSite.com/products.aspx?category=Kids
http://www.yourSite.com/products.aspx?category=Science
http://www.yourSite.com/products.aspx?category=Biology
We are going to use a less used feature of Asp.Net i.e. "Request.PathInfo" using which we will able handle
URLs which are as below
http://www.yourSite.com/products.aspx/Kids
http://www.yourSite.com/products.aspx/Science
http://www.yourSite.com/products.aspx/Biology
This is one of the simplest approach to Handle URL Rewriting.  Now Lets start implementing it, before we go ahead check out the folder structure of the DemoCode for this article which is as below.
Lets Discuss one File at a time
  • Default.aspx: This file contains simple Div Tag with 3 links point to Product.aspx with desired URLs. Check out following code for the same. Check out URLs.



  • Product.aspx: HTML of Product.aspx contains following simple code.


    code behind of Product.aspx is as follows








    protected void Page_Load(object sender, EventArgs e)
        {
            switch (Request.PathInfo.Substring(1))
            { 
                case "Kids":
                    Response.Write("This is Kids Section");
                    break;
                case "Science":
                    Response.Write("This is Science Section");
                    break;
                case "Biology":
                    Response.Write("This is Biology Section");
                    break;
            }
    
            Response.Write("
    
    
    Check out the URL");
        }
        protected void Button_Click(object sender, EventArgs e)
        {
            Response.Write("URL is Not Changing After PostBack");
        }

    This is very simple way to implement and understand which category is being called. upto this point code can work very well. But to make sure that on post back also i.e. on button click on Product.aspx page same URL should be maintained, we have to write Control Adapter which we have written in "HandlePostBacks.cs" file
  • HandlePostBacks.cs:  In this file we have overriden Render function of Control Adapter class to rewrite the Raw URL during postbacks. check out following code.











    public class HandlePostBacks : System.Web.UI.Adapters.ControlAdapter
    {
        protected override void Render(HtmlTextWriter writer)
        {
            base.Render(new RewriteForPostBack(writer));
        }
    }
    
    public class RewriteForPostBack : System.Web.UI.HtmlTextWriter
    {
        public RewriteForPostBack(HtmlTextWriter writer) : base(writer)
        {
            this.InnerWriter = writer.InnerWriter;
        }
    
        public RewriteForPostBack(System.IO.TextWriter writer) : base(writer)
        {
            base.InnerWriter = writer;
        }
    
        public override void WriteAttribute(string name, string value, bool fEncode)
        {
            if (name == "action")
            {
                HttpContext context;
                context = HttpContext.Current;
                value = context.Request.RawUrl;
                       }
            base.WriteAttribute(name, value, fEncode);
        }
    }

    Now we have almost done with our logic, now what remains is to register above adapter so that it get called automatically. For this we will write logic in "postback.browser" file

  • Postback.browser: We write simple logic which tells .net which adapter control should be used, check following code.



    
        
          
        
      

And we are done with the implementation DOWNLOAD demo code and check it out, very simple and can implement easily on other pages.
Download Demo Code here --> UrlRewitting-Simple Approach 1.zip Submit this story to DotNetKicks

Read more...