Saturday, July 31, 2010

How to convert HTML files to aspx files automatically - Html file converter for asp.net

Please note: This tool aim to create a asp.net web application based on html files provided. 

Download Installer - (X86)
Download Source
Download .EXE File (X86) Only 
  1. Download and install HtmlAspxFileConverter
  2. Run from the link provided in the Programmes (HtmlAspxFileConverter)
  3. Select a source direcotry where you have static html files css java scripts and other files
  4. Select a destination folder. If destination folder excists programme deletes the folder without any prompt and if the folder does not exists creates a new folder with the give path or in a case of invalid path provide you an error
  5. Enter an namespace for the asp.net web application
  6. Click on convet button.
  7. Open up visual studio and select new project
  8. Select Web tab and select Asp.net Empty Web Application
  9. Provide suitable name and click ok
  10. Change the namespace/assembly name with the name space provide to convert html in HtmlAspxFileConverter
  11. Copy all the files convertered by HtmlAspxFileConverter to the WebApplication folder. 
  12. In the solution explorer click on show all files option at the top
  13. Select non included aspx pages and just copied other folders and files and rightclick
  14. Select Include In Project option 
    For VB please change the source and run the programme
    Source:
    public partial class HtmlAspxFileConverter : Form
    {
        #region Attributes
     
        string strNameSpace = string.Empty;
        string head = @"
            <head runat=""server"">
                {0}
            </head>
        ";
        string body = @"
            <body{0}>
                <form id=""form1"" runat=""server"">
                    {1}
                </form>
            </body>
        ";   
        private string code = @"
            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Web;
            using System.Web.UI;
            using System.Web.UI.WebControls;
     
            namespace {0}
            {{
                public partial class {1} : Page
                {{
                    protected void Page_Load(object sender, EventArgs e)
                    {{
     
                    }}
                }}
            }}
        ";
        private string designer = @"
            namespace {0}
            {{
                public partial class {1}
                {{
                }}
            }}
        ";
        private string header = @"<%@ Page Language=\""C#\"" AutoEventWireup=\""true\"" 
                                CodeBehind=\""{0}.cs\"" Inherits=\""{1}.{2}\"" %>";
        string[] keywords = { "abstract""event""new""struct""as""explicit""null switch""base", 
                                "extern""object""this""bool""false""operator""throw""break", 
                                "finally""out""true""byte""fixed""""override""try", 
                                "case""float""params""typeof""catch""for""private""uint",
                                "char""foreach""protected""ulong""checkek","goto""public", 
                                "unchecked""class""if""readonly""unsafe""const""implicit", 
                                "ref""ushort""continue""in""return""using""decimal""int", 
                                "sbyte""virtual""default""interface""sealed""volatile""delegate",
                                "internal""short""void""do""is""sizeof""while""double""lock",
                                "stackalloc""else""long""static""enum""namespace""string" };
     
        #endregion
     
        #region Constructors
     
        public HtmlAspxFileConverter()
        {
            InitializeComponent();
        }
     
        #endregion
     
        #region Support Methods
     
        private void ConverHtmlFileToAspxFiles(DirectoryInfo o, DirectoryInfo n)
        {
            CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
            TextInfo textInfo = cultureInfo.TextInfo;
            foreach (FileInfo f in o.GetFiles())
            {
                string nfn = f.FullName.Replace(o.FullName, n.FullName);
                nfn = nfn.Replace(f.Name, textInfo.ToTitleCase(f.Name));
                if (f.Extension.ToLower().Equals(".html") || f.Extension.ToLower().Equals(".htm"))
                    this.SaveAsAspx(f, new FileInfo(nfn));
                else
                    File.Copy(f.FullName, nfn);
            }
            foreach (DirectoryInfo c in o.GetDirectories())
            {
                string ndn = c.FullName.Replace(o.FullName, n.FullName);
                ndn = ndn.Replace(c.Name, textInfo.ToTitleCase(c.Name));
                Directory.CreateDirectory(ndn);
                this.ConverHtmlFileToAspxFiles(c, new DirectoryInfo(ndn));
            }
        }
        private void SaveAsAspx(FileInfo h, FileInfo a)
        {
            CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
            TextInfo textInfo = cultureInfo.TextInfo;
            string fn =  a.FullName;
            string fileName=string.Empty;
            if(fn.Contains("html"))fileName = fn.Replace("html""aspx");
            else if (fn.Contains("Html")) fileName = fn.Replace("Html""aspx");
            else if (fn.Contains("htm")) fileName = fn.Replace("htm""aspx");
            else if (fn.Contains("Htm")) fileName = fn.Replace("Htm""aspx");  
            string classFileName = new FileInfo(fileName).Name;
            string currentFolder = fileName.Replace(classFileName,string.Empty);
            string className = string.Empty;
            if (a.Name.Contains(h.Extension)) className = a.Name.Replace(h.Extension, string.Empty);
            else
            {
                string ext = textInfo.ToTitleCase(h.Extension);
                className = a.Name.Replace(ext, string.Empty);
            }
            if (keywords.ToList<string>().Exists(x => x.Equals(className.ToLower()))) 
                className = string.Format("_{0}", className);
            File.WriteAllText(Path.Combine(currentFolder, string.Format("{0}.cs", 
                classFileName)), string.Format(code, this.strNameSpace, className));
            File.WriteAllText(Path.Combine(currentFolder, string.Format("{0}.designer.cs", 
                classFileName)), string.Format(designer, this.strNameSpace, className));
            string html = File.ReadAllText(h.FullName);
            using (StreamWriter stream = new StreamWriter(fileName))
            {                
                stream.WriteLine(string.Format(header, classFileName, this.strNameSpace, className));
                stream.WriteLine("<html>");
                int s = html.ToLower().IndexOf(">", html.ToLower().IndexOf("<head")) + 1;
                int e = html.ToLower().IndexOf("</head") - 1;
                string headContent = e - s > 0 ? html.Substring(s, e - s) : string.Empty;
                stream.Write(string.Format(head, headContent));                
                s = html.ToLower().IndexOf("<body") + 5;
                e = html.IndexOf(">", s);
                string bodyAttributes = string.Empty;
                if (s != e && e > s) bodyAttributes = html.Substring(s, e - s);
                if (bodyAttributes.Contains(">") || bodyAttributes.Contains(">")) 
                    bodyAttributes = string.Empty;                
                s = html.ToLower().IndexOf(">", html.ToLower().IndexOf("<body")) + 1;
                e = html.ToLower().IndexOf("</body") - 1;
                string bodyContent = e - s > 0 ? html.Substring(s, e - s) : string.Empty;
                string[] exts = { "html","Html","htm","Htm"};
                foreach (string ext in exts) bodyContent = bodyContent.Replace(ext, "aspx");
                stream.Write(string.Format(body, bodyAttributes, bodyContent));
                stream.WriteLine("</html>");
                stream.Close();
            }
                
        }
        private void btnConvert_Click(object sender, EventArgs e)
        {
            try
            {
                if (string.IsNullOrEmpty(this.txtNameSpace.Text)) throw new Exception();
                this.strNameSpace = this.txtNameSpace.Text;
                DirectoryInfo s = new DirectoryInfo(this.txtSource.Text);
                if (!s.Exists) { MessageBox.Show("Destination folder doesnot exists"); return; }
                DirectoryInfo d = new DirectoryInfo(this.txtDestiation.Text);
                if (d.Exists) this.DeleteFolder(d);
                Directory.CreateDirectory(d.FullName);
                this.toolStripStatusLabel1.Text = "Converting, please wait...";
                this.SetControlStatus(false);
                this.ConverHtmlFileToAspxFiles(s, d);
                this.SetControlStatus(true);
                this.toolStripStatusLabel1.Text = "Conversion Finished.";
            }
            catch
            {
                MessageBox.Show("There is a problem");
            }
     
     
        }
        private void SetControlStatus(bool status)
        {
            this.txtSource.Enabled = 
            this.txtDestiation.Enabled = 
            this.txtNameSpace.Enabled = 
            this.btnConvert.Enabled = 
            this.btnSelectDestination.Enabled = 
            this.btnSelectSource.Enabled = status;
        }
        public void DeleteFolder(DirectoryInfo d)
        {
            foreach (FileInfo f in d.GetFiles())
                File.Delete(f.FullName);
            foreach (DirectoryInfo c in d.GetDirectories())
                this.DeleteFolder(c);
            Directory.Delete(d.FullName);
        }
     
        #endregion
    }

    How to rename all the files in a directory using c# (Convert to title case)

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
     
        string on = @"C:\PathOldFolder";
        string nn = @"C:\PathNewFolder";
        Directory.CreateDirectory(nn);
        this.ChangeFileNamesToTitleCase(new DirectoryInfo(on), new DirectoryInfo(nn));
    }
     
    public void ChangeFileNamesToTitleCase(DirectoryInfo o, DirectoryInfo n)
    {
        CultureInfo cultureInfo   = Thread.CurrentThread.CurrentCulture;
        TextInfo textInfo = cultureInfo.TextInfo;
        foreach (FileInfo f in o.GetFiles())
        {
            string nfn = f.FullName.Replace(o.FullName, n.FullName);
            nfn= nfn.Replace(f.Name, textInfo.ToTitleCase(f.Name));
            File.Copy(f.FullName, nfn);
        }
        foreach (DirectoryInfo c in o.GetDirectories())
        {
            string ndn = c.FullName.Replace(o.FullName, n.FullName);
            ndn = ndn.Replace(c.Name, textInfo.ToTitleCase(c.Name));
            Directory.CreateDirectory(ndn);
            this.ChangeFileNamesToTitleCase(c, new DirectoryInfo(ndn));
        }
                
    }

    Friday, July 30, 2010

    How to handle errors and other messages in asp.net pages (A centralized approach)

    Demo:
    Idea is to have a single method in the PageBase called ShowMessage(...) and whenever we need to need to display message we can have pages inherit from PageBase and add PlaceHoder to the page and call this.ShowMessage(...)

    BasePage And Message Type Enumaration:

    public enum MessageType { Error, Information, Success }
     
    public class PageBase : Page
    {
        public void ShowMessage(PlaceHolder phMessage, string message, MessageType type)
        {
            if (phMessage != null)
            {
                Panel panel = new Panel() { CssClass = string.Format("{0}Message", 
                    type.ToString()) };
                Label lblMessage = new Label() { Text = message, CssClass = "MessageText" };
                panel.Controls.Add(lblMessage);
                phMessage.Controls.Add(panel);
            }
        }
    }

    Page - Code:

    public partial class TestPageBase
    {
        protected void Process(object sender, EventArgs e)
        {
            try
            {
                this.btnSave.Enabled = true;
                ///
                /// just fake exception to demonstrate
                ///
                if (DateTime.Now.Second % 3 == 0) throw new Exception();
                this.ShowMessage(this.phMessage, "Processed... You need to save data to proceed...",
                    MessageType.Information);
            }
            catch
            {
                this.ShowMessage(this.phMessage, "There is problem with processing data", 
                    MessageType.Error);
                this.btnSave.Enabled = false;
            }
        }
        protected void Save(object sender, EventArgs e)
        {
            try
            {
                ///
                /// save data
                ///
                this.ShowMessage(this.phMessage, "Data saved successfully...", 
                    MessageType.Success);
            }
            catch
            {
                this.ShowMessage(this.phMessage, "There is a problem of saving data", 
                    MessageType.Success);
            }
        }
    }

    Page - Markup:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
     <style type="text/css">
      div.ErrorMessage,
      div.InformationMessage,
      div.SuccessMessage { padding:5px; }
      div.ErrorMessage { border:solid 1px #f00background-color:#fb9d9dcolor:#000 !important; }
      div.InformationMessage { bordersolid 1px #f59600background-color:#fac26a; }
      div.SuccessMessage { border:solid 1px #298012background-color:#82cf6e;  }    
     </style>
     <script runat="server">            
     </script>
     <script language="javascript" type="text/javascript">
     </script>
    </head>
    <body>    
     <form id="form1" runat="server">   
      <asp:PlaceHolder runat="server" ID="phMessage" />             
      <div>
       <asp:Button runat="server" ID="btnProcess" Text="Process" OnClick="Process" />
       <asp:Button runat="server" ID="btnSave" Text="Save" OnClick="Save" />
      </div>
     </form>
    </body>
    </html>

    
    

    How to find folder/direcotry size - C#

    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write(FindFolderSize(new DirectoryInfo(Server.MapPath("~")), UnitType.KB, 0).ToString() + " KB");
        Response.Write("<br />");
        Response.Write(FindFolderSize(new DirectoryInfo(Server.MapPath("~")), UnitType.MB, 2).ToString() + " MB");
        Response.Write("<br />");
        Response.Write(FindFolderSize(new DirectoryInfo(Server.MapPath("~")), UnitType.GB, 5).ToString() + " GB");
    }
     
    public enum UnitType { KB = 1, MB = 2, GB = 3 }
    /// <summary>
    /// Find foler size
    /// </summary>
    /// <param name="d">Target folder</param>
    /// <param name="u">Unit type [KB, MB, GB]</param>
    /// <param name="r">Number to digits to round up</param>
    /// <returns></returns>
    public double FindFolderSize(DirectoryInfo d, UnitType u, int r)
    {
        double divider = Math.Pow(1024, (int)u);
        double size = 0;
        foreach (FileInfo f in d.GetFiles())
            size += Convert.ToDouble(f.Length) / divider;
        foreach (DirectoryInfo c in d.GetDirectories())
            size += this.FindFolderSize(c, u, r);
        return Math.Round(size, r);
    }

    How to bubble up an event from usercontrol to parent page(control) (Part 2 - Without Delegates)- Asp.net

    Without Delegates
    Please use OnBubbleEvent of the page and caste the source (first argument) to required control (in this case a button) and compare Id or you can use object compare

    UserControl (Code and Markup)
    Markup
    <%@ Control Language="C#" 
                AutoEventWireup="true" 
                CodeBehind="WebUserControl.ascx.cs" 
                Inherits="ActiveTest.WebUserControl" %>
    <asp:Button runat="server" ID="btnUpdate" Text="Update" />
     
    Code

    namespace ActiveTest
    {
        public partial class WebUserControl : UserControl
        {
            public string UpdateButton         
            { 
                get { return this.btnUpdate.ID; } 
            }    
        }
     
    }

    Consuming Page

    <%@ Page Language="C#" %>
    <%@ Register Src="~/WebUserControl.ascx" TagName="wuc" TagPrefix="active" %>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <script runat="server"> 
            protected override bool OnBubbleEvent(object source, EventArgs args)
            {
                Button btnUpdate = source as Button;
                if (btnUpdate != null && btnUpdate.ID == this.wucTest.UpdateButton)
                {
                    ///
                    /// Update/ or do any requred actions
                    ///
                }
                return base.OnBubbleEvent(source, args);
            }
        </script>
        <script language="javascript" type="text/javascript">
        </script>
    </head>
    <body>    
        <form id="form1" runat="server">        
            <div>
                <active:wuc runat="server" ID="wucTest" />
            </div>
        </form>
    </body>
    </html>

    How to combine two asp.net Menu Controls with single site map and populate second menu based on first menu selection

    Demo:
     
    To handle multiple asp.net menu controls based on single site map data source:
    1. Convert all the links of the first menu to perform a postback instead of rendering as links.
    2. Use link button instead of hyperlink
    3. In the code behind (usually in the master page) handle link button event and read the site map in to XPathDocuemnt, create navigator and perform a XPath query for the relevent node
    4. Populate the second menu with the selected XML node
    5. Use an recursive method to populate all the child menu items
    6. In this article I have not used a application variable, but it is better to hold the Web.sitemap file (XPathNavigator) instead of reading on each menu click.
    7. I have used empty namespace, but if you use a namespace (usually sitemap file comes with a namespace) you have to change to XPath logoc accordingly.
    Site.Master page:
    <%@ Master Language="C#" %>
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head id="Head1" runat="server">
        <script runat="server">
            protected void PopulateLeftNagivation(object sender, CommandEventArgs e)
            {
                this.mnuLeftNavigation.Items.Clear();
                XPathDocument doc = new XPathDocument(Server.MapPath("~/Web.sitemap"));
                XPathNavigator navigator = doc.CreateNavigator();
                XPathNodeIterator reader = navigator.Select(
                    string.Format("/siteMap/siteMapNode[@url='']/siteMapNode[@url='{0}']/siteMapNode",
                    Path.GetFileName(e.CommandArgument.ToString())));
                this.BuildLeftMenu(this.mnuLeftNavigation.Items, reader);
            }
            private void BuildLeftMenu(MenuItemCollection items, XPathNodeIterator reader)
            {
                while (reader.MoveNext())
                {
                    MenuItem item = new MenuItem(reader.Current.GetAttribute("url"string.Empty),
                        reader.Current.GetAttribute("title"string.Empty));
                    items.Add(item);
                    if (reader.Current.HasChildren)
                        this.BuildLeftMenu(item.ChildItems,
                            reader.Current.SelectChildren("siteMapNode"string.Empty));
                }
            }        
        </script>
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
        </asp:ContentPlaceHolder>
    </head>
    <body>
        <form id="Form1" runat="server">
        <asp:ScriptManager runat="server" ID="ScriptManager2"></asp:ScriptManager>
        <div class="page">
            <div class="main">
                    <asp:UpdatePanel runat="server" ID="upnlNavigation">
                        <ContentTemplate>
                            <div class="NavigationWrapper">
                                <div class="TopNanvigation">
                                    <asp:SiteMapDataSource runat="server" ID="SiteMapDataSource" ShowStartingNode="false" />
                                    <asp:Menu runat="server" ID="mnuTopNavigation" Orientation="Horizontal" DataSourceID="SiteMapDataSource"
                                        StaticDisplayLevels="1" MaximumDynamicDisplayLevels="0">
                                        <StaticItemTemplate>
                                            <asp:LinkButton 
                                                runat="server" 
                                                ID="lnkItem" 
                                                CommandArgument='<%# Eval("NavigateUrl") %>' 
                                                OnCommand="PopulateLeftNagivation">
                                                <%# Eval("Text"%>
                                            </asp:LinkButton>
                                        </StaticItemTemplate>
                                    </asp:Menu>
                                </div>
                                <div class="LeftNavigation">
                                    <asp:Menu runat="server" ID="mnuLeftNavigation" />
                                </div>
                            </div>
                        </ContentTemplate>
                    </asp:UpdatePanel>
                <div class="MainContent">
                    <asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server"/>
                </div>
            </div>
            <div class="clear">
            </div>
        </div>
        <div class="footer">
            
        </div>
        </form>
    </body>
    </html>

    Web.sitemap file (please not no name space)
    <?xml version="1.0" encoding="utf-8" ?>
    <siteMap>
        <siteMapNode url="" title=""  description="">
          <siteMapNode url="Page1.aspx" title="Item 1"  description="">
            <siteMapNode url="SubPage11.aspx" title="Sub Item 11" />
            <siteMapNode url="SubPage12.aspx" title="Sub Item 12" >
              <siteMapNode url="SubPage121.aspx" title="Sub Item 121" />
              <siteMapNode url="SubPage122.aspx" title="Sub Item 122" />
              <siteMapNode url="SubPage123.aspx" title="Sub Item 123" />
            </siteMapNode>
            <siteMapNode url="SubPage13.aspx" title="Sub Item 13" />
            <siteMapNode url="SubPage14.aspx" title="Sub Item 14" />
            <siteMapNode url="SubPage15.aspx" title="Sub Item 15" />
          </siteMapNode>
          <siteMapNode url="Page2.aspx" title="Item 2"  description="">
            <siteMapNode url="SubPage21.aspx" title="Sub Item 21" />
            <siteMapNode url="SubPage22.aspx" title="Sub Item 22" />
            <siteMapNode url="SubPage23.aspx" title="Sub Item 23" />
          </siteMapNode>
          <siteMapNode url="Page3.aspx" title="Item 3"  description="">
            <siteMapNode url="SubPage31.aspx" title="Sub Item 31" />
            <siteMapNode url="SubPage32.aspx" title="Sub Item 32" />
            <siteMapNode url="SubPage33.aspx" title="Sub Item 33" />
            <siteMapNode url="SubPage34.aspx" title="Sub Item 34" />
          </siteMapNode>
          <siteMapNode url="Page4.aspx" title="Item 3"  description="">
            <siteMapNode url="SubPage41.aspx" title="Sub Item 41" />
            <siteMapNode url="SubPage42.aspx" title="Sub Item 42" />
          </siteMapNode>
          <siteMapNode url="Page5.aspx" title="Item 3"  description="">
            <siteMapNode url="SubPage51.aspx" title="Sub Item 51" />
            <siteMapNode url="SubPage52.aspx" title="Sub Item 52" />
            <siteMapNode url="SubPage53.aspx" title="Sub Item 53" />
            <siteMapNode url="SubPage54.aspx" title="Sub Item 54" />
          </siteMapNode>
        </siteMapNode>
    </siteMap>

    Azure Storage Account Types

    Defferent Types of Blobs Block blobs store text and binary data. Block blobs are made up of blocks of data that can be managed individually...