C# Coding Standards and Best Programming Practices

I was reading a best practices document created by the DotNetSpider team which covered many aspects of programming in .NET. I was really impressed by it and I think its a very good reference document. So I’ve decided to make a series of posts where I’ll post sections of their document covering a specific topic.

A Semi-Dynamic Sitemap Solution

I was creating a website which had pages with multiple views. I wanted a fairly simple sitemap solution, without creating any custom sitemap provider, which could show the current view name in the breadcrumb trail like this -

Home » Parent Page » Current Page » Current View 1
Home » Parent Page » Current Page » Current View 2

So here’s what I did to achieve that -

MasterPage.Master:

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>CMS ::</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:SiteMapPath ID="SiteMapPath1" runat="server" OnPreRender="SiteMapPath1_PreRender" PathSeparator=" :  " RenderCurrentNodeAsLink="True">
            </asp:SiteMapPath>
        </div>
        <div>
            <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
            </asp:ContentPlaceHolder>
        </div>
    </form>
</body>
</html>

MasterPage.master.cs:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;

public partial class MasterPage : System.Web.UI.MasterPage
{
    private string _currentViewName = string.Empty;
    public string CurrentViewName
    {
        get { return _currentViewName; }
        set { _currentViewName = value; }
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(SiteMap_SiteMapResolve);
    }
    protected void SiteMapPath1_PreRender(object sender, EventArgs e)
    {
        //If there is a current view name defined then add a child node to the breadcrumb trail.
        if (!string.IsNullOrEmpty(CurrentViewName))
        {
            SiteMapNodeItem sepItem = new SiteMapNodeItem(-1, SiteMapNodeItemType.PathSeparator);
            ITemplate sepTemplate = SiteMapPath1.PathSeparatorTemplate;
            if (sepTemplate == null)
            {
                Literal separator = new Literal();
                separator.Text = SiteMapPath1.PathSeparator;
                sepItem.Controls.Add(separator);
            }
            else
            {
                sepTemplate.InstantiateIn(sepItem);
            }
            sepItem.ApplyStyle(SiteMapPath1.PathSeparatorStyle);

            SiteMapNodeItem viewItem = new SiteMapNodeItem(-1, SiteMapNodeItemType.Current);
            Literal viewName = new Literal();
            viewName.Text = CurrentViewName;
            viewItem.Controls.Add(viewName);
            viewItem.ApplyStyle(SiteMapPath1.CurrentNodeStyle);

            SiteMapPath1.Controls.AddAt(-1, sepItem);
            SiteMapPath1.Controls.AddAt(-1, viewItem);
        }
        else //...if not then don't show the current node as a link.
        {
            SiteMapPath mySMP = (SiteMapPath)sender;
            mySMP.RenderCurrentNodeAsLink = false;
            mySMP.DataBind();
        }
    }
    private SiteMapNode SiteMap_SiteMapResolve(Object sender, SiteMapResolveEventArgs e)
    {
        SiteMapNode currentNode = SiteMap.CurrentNode.Clone(true);         

        //If there is a current view defined then set the URLs in the breadcrumb trail 
        //so that they point to the correct view. For example:
        //Home (Home.aspx) > News (News.aspx?View=0) > Edit (News.aspx?View=1)
        if (!string.IsNullOrEmpty(CurrentViewName))
        {
            string currentRequest = e.Context.Request.UrlReferrer.PathAndQuery;

            if (currentNode != null)
                currentNode.Url = currentRequest;
        }

        return currentNode;
    }
}

Now you are all set. To put this code in action, just declare a curent view name like this in your pages wherever needed:

((MasterPage)this.Master).CurrentViewName = "News Listing";

This solution was inspired by this blog post.

Workaround for Response.Redirect

This is a workaround to do a redirect while using ASP.NET AJAX Framework. The traditional Response.Redirect method can not be used since it is not compatible with the .NET AJAX framework.

StringBuilder sb = new StringBuilder();
sb.Append("<script language=\"javascript\">\n");
sb.Append("function Redirect()\n");
sb.Append("{\n");
sb.Append("     window.parent.location.href = \"" + ResolveUrl(myURL) + "\";\n");
sb.Append("}\n");
sb.Append("</script>\n");

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "Redirect", sb.ToString());
myBtn.Attributes.Add("onclick", "return Redirect();");

How to extract URLs (href property) from HTML

protected ArrayList getURL(string txtIn)
{
    ArrayList outURL = new ArrayList();
    Regex r = new Regex("href\\s*=\\s*(?:(?:\\\"(?[^\\\"]*)\\\")|(?[^\\s]* ))"</span>);
    MatchCollection mc1 = r.Matches(txtIn);

    foreach (Match m1 in mc1)
    {
        foreach (Group g in m1.Groups)
        {
            outURL.Add(g.Value);
        }
    }

    return outURL;
}</pre>

How to remove all special characters from a string

protected string StripSpecChars(string txtIn)
{
    string txtOut = Regex.Replace(txtIn, @"[^\w\.@-]", "").Trim();
    return txtOut;        
}