Thursday, April 22, 2010

Directory Browser using Asp.Net

Demo:
Notes - Functionality:
  1. RootDirectory default to web application physical directory, using RootDirecotry property you can change it to any destination if you want
  2. Directory browser lists all the child directories starting from RootDiectory as a treeview
  3. When you click on any listed directory in the treeview it does a postback and show the directory full path in the text box at the top
  4. At the initial state text box get the value of root direcotry
Notes - Implementation:
  1. I have implemented direcotory browser as a custom web control. Inheriting WebControl  class and INamingContainer interface.
  2. Default property of this custom web control is DirecotryBrowser
  3. Default property of the directory browser is RootDirecotry
  4. SelectedDirectoryName is the output property that you can consume
  5. In the initializaton phase, control calls CreateControlHeirarchy method to create its controls
  6. Inside CreateControlHeirarchy it calls a method call AddChildDirectories which accepts two parameters, TreeNode and DirectoryInfo
  7. AddChildDirectories method lists all the child directories inside a given directory and then its call itslef recursively to list direcotries of child directories of the given directory
  8. Finally RenderBeginTag, and RenderEndTag wrap the control with <div> tag as my design team always prefer to have div around custom controls over default <span> tag (you would inherit Panel to get rid of this problem but I didnt)
Directory browser : asp.net 4.0
    [DefaultProperty("RootDirectory")]
    public class DirectoryBrowserField : WebField
    {
        #region Events
 
        public event EventHandler SelectedDirectoryChanged;
 
        #endregion
 
        #region Attributes
 
        TextBox txtDirectoryName = new TextBox();
        TreeView treeView = new TreeView();
        PlaceHolder contentPlaceHodler = new PlaceHolder();
        string baseDirecotry = string.Empty;
 
        #endregion
 
        #region Properties
 
        [DefaultValue("")]
        [Bindable(true)]
        public string RootDirectory { get; set; }
 
        [DefaultValue("ActiveTextBoxCssClass")]
        [Bindable(true)]
        public string TextBoxCssClass { get; set; }
 
        [DefaultValue("ActiveTreeViewCssClass")]
        [Bindable(true)]
        public string TreeViewCssClass { get; set; }
 
        [DefaultValue("")]
        [Bindable(true)]
        public string SelectedDirectoryName { get; set; }
 
        [DefaultValue(false)]
        [Bindable(true)]
        public bool ShowFullPath { get; set; }
 
        #endregion
        
        #region Constructors
 
        public DirectoryBrowserField()
        {
            this.Initialize();
        }
 
        #endregion
 
        #region Methods
 
        private void Initialize()
        {
            this.baseDirecotry = HttpContext.Current.Server.MapPath("~\\");
            this.SelectedDirectoryName = this.RootDirectory = 
                HttpContext.Current.Request.PhysicalApplicationPath;
            this.TextBoxCssClass = "TextBox";
            this.TreeViewCssClass = "TreeView";
            this.CssClass = this.GetType().Name;
            this.ShowFullPath = false;
        }
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if(!this.ChildControlsCreated)
                this.CreateControlHeirarchy();
        }
        public void CreateControlHeirarchy()
        {
            if(!this.RootDirectory.Contains(":\\"))
            {
                if (this.RootDirectory.StartsWith("~/"))
                    this.RootDirectory = 
                        this.RootDirectory.Replace("~/", "~\\").Replace("/", "\\");
                if (this.RootDirectory.StartsWith("/") || this.RootDirectory.StartsWith("\\"))
                    this.RootDirectory = 
                        string.Format("~{0}", this.RootDirectory.Replace("/", "\\"));
                if (this.RootDirectory.StartsWith("~\\"))
                    this.RootDirectory = HttpContext.Current.Server.MapPath(this.RootDirectory);
            }
            if (Directory.Exists(this.RootDirectory))
            {
                this.txtDirectoryName.CssClass = this.TextBoxCssClass;
                this.SelectedDirectoryName = this.RootDirectory;
                this.txtDirectoryName.Text = this.ResolveDirecotry();
                this.contentPlaceHodler.Controls.Add(this.txtDirectoryName);
                treeView.CssClass = this.TreeViewCssClass;
                Panel panel = 
                    new Panel() { CssClass = string.Format("{0}Wrapper", this.TreeViewCssClass) };
                DirectoryInfo root =new DirectoryInfo(this.RootDirectory);
                TreeNode node = 
                    new TreeNode(string.Format(".\\{0}", root.Name), this.RootDirectory);
                treeView.Nodes.Add(node);
                this.AddChildDirectories(node, root);
                foreach (TreeNode n in node.ChildNodes) n.Collapse();
                treeView.SelectedNodeChanged += new EventHandler(SelectedNodeChanged);
                panel.Controls.Add(treeView);
                this.contentPlaceHodler.Controls.Add(panel);
                this.Controls.Add(contentPlaceHodler);
                this.ChildControlsCreated = true;
            }
        }
        private void SelectedNodeChanged(object sender, EventArgs e)
        {
            this.SelectedDirectoryName = this.treeView.SelectedNode.Value;
            this.txtDirectoryName.Text = this.ResolveDirecotry();
            if (this.SelectedDirectoryChanged != null) this.SelectedDirectoryChanged(this, e);
        }
        private void AddChildDirectories(TreeNode node, DirectoryInfo direcotry)
        {
            foreach (DirectoryInfo child in direcotry.GetDirectories())
            {
                TreeNode childNode = new TreeNode(child.Name, child.FullName);
                node.ChildNodes.Add(childNode);
                if (child.GetDirectories().Count() > 0)
                    this.AddChildDirectories(childNode, child);
            }
        }
        private string ResolveDirecotry()
        {
            if (!this.ShowFullPath)
                return string.Format(".\\{0}",
                    this.SelectedDirectoryName.Replace(this.baseDirecotry, string.Empty));
            return this.RootDirectory;
        }
        protected override void RenderContents(HtmlTextWriter writer)
        {
            this.RenderFieldLabel(writer);
            StringBuilder sb = new StringBuilder();
            HtmlTextWriter htw = new HtmlTextWriter(new StringWriter(sb));
            contentPlaceHodler.RenderControl(htw);
            base.RenderFieldControl(writer,sb.ToString());
            this.RenderFieldValidator(writer);
        }
 
        #endregion
    }

Next steps
  1. Add a test page to your web project
  2. Add Register your control <%@ Register Assembly="Y" Namespace="X" TagPrefix="active" %>
  3. Utilise your control 
  4. <active:DirectoryBrowser runat="server" ID="dbSample" />
Using Direcotry Browser
        protected void Page_Load(object sender, EventArgs e)
        {
            this.dbfBrowse.SelectedDirectoryChanged += new EventHandler(dbfBrowse_SelectedDirectoryChanged);
        }
 
        void dbfBrowse_SelectedDirectoryChanged(object sender, EventArgs e)
        {
            DirectoryInfo d = new DirectoryInfo(this.dbfBrowse.SelectedDirectoryName);
            {
                foreach (FileInfo f in d.GetFiles())
                {
                    string ext = f.Extension.ToLower();
                    if (ext.Equals("txt") || ext.Equals("doc") || ext.Equals("pdf"))
                        lbxFiles.Items.Add(new ListItem(Path.GetFileName(f.Name), f.Name));
                }
            }
        }

Asp.net Forums

Friday, April 09, 2010

Can't write to a readonly object Source: NHibernate

This happens when you try to flush the default session with ReadOnlyCache objects. So in your ReadOnlyCached entity repository methods use:
using (new SessionScope(FlushAction.Never))
{
    entityRepository.FindAll();
}

Monday, March 22, 2010

Load Html Page inside .aspx page

Well, there are couple of considerations
  1. Method 1: If you can thrust the html you can use a simple Web Control (I have called it as HTMLContent)
  2. Method 2: If you can't thrust the html you can use IFrame and use JQuery to append the IFrame content using your html conent
Implementation : Asp.Net 4.0 (C#)
Html Content Web Control

public class HtmlConent : WebControl
{
    public string Html { get; set; }
    public override void RenderBeginTag(HtmlTextWriter writer)
    {
        writer.Write(string.Format("<div class=\"{0}\">", this.GetType().Name));
        base.RenderBeginTag(writer);
    }
    protected override void RenderContents(HtmlTextWriter writer)
    {
        writer.Write(Html);
    }
    public override void RenderEndTag(HtmlTextWriter writer)
    {
        base.RenderEndTag(writer);
        writer.Write("</div>");
    }
}

Test page : Both Method 1 and Method 2 included

<%@ Page Language="C#" AutoEventWireup="true"  %>
<%@ Register Namespace="Active.Web.UI.Controls" 
           Assembly="Active.Web.UI.Controls" TagPrefix="active" %>
<!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 id="Head1" runat="server">
    <title>Test Page</title>
    <script src="Scripts/jquery-1.4.1.min.js" 
           type="text/javascript" language="javascript"></script>
    <script runat="server">
        private string startupScript = @"
            $(document).ready(function () {{
                $(""body"", $(""iframe.ExternalPage"").contents()).html(""{0}"");
            }});
        ";       
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            string page = @"
            <html>
                <head>
                    <title>External Html Page Title<title>
                </head>
                <body>
                    <div>
                        <h1>External Html Page Title</h2>
                        <p>External Html Page Content</p>
                    </div>
                </body>
            </html>
            ";
            int index = page.IndexOf("<body")+6;
            string content = page.Substring(index, page.IndexOf("</body") - index);
            ///
            /// Method 1
            ///
            hcContent.Html = content;
            ///
            /// Method 2
            ///
            this.Page.ClientScript.RegisterStartupScript(
                   this.GetType(), this.GetType().Name,
                   string.Format(this.startupScript, 
                   content.Replace("\"", "'")
                          .Replace("\n",string.Empty)
                          .Replace("\r",string.Empty)), true);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <active:HtmlConent runat="server" ID="hcContent" />
        <iframe runat="server" id="iframeConent" class="ExternalPage" />
    </form>
</body>
</html>

Monday, February 22, 2010

Opening a new window after executing some code in a postback - Asp.Net

If we need to do a postback and then open a new window( equvalent to target = _blank) if a conditon is true, I think if we register a 'window.open(....)' script block on the click event of the link button when condition is true, it seems it opens the new window on your postback.
PS: RootUrl is bit critical here: I have tested RootUrl property. However you can use it if you want, but if you get problems please have a web.config configrued value for root url. We never know where it go wrong. It might work on local but when you deploy it to live or a in some extrem conditions it might stop working.

Here is an example:
<%@ Page Language="C#" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Test Page</title>
    <script runat="server">
        public string RootUrl
        {
            get
            {
                Uri requestUri = Context.Request.Url;
                HttpRequest request = Context.Request;
                string rootUrl = string.Format("{0}{1}{2}{3}{4}",
                    requestUri.Scheme,
                    Uri.SchemeDelimiter,
                    requestUri.Host,
                    requestUri.IsDefaultPort ? 
                        string.Empty : string.Format(":{0}", requestUri.Port),
                    request.ApplicationPath);
                return rootUrl.EndsWith("/") ? rootUrl : 
                        string.Format("{0}/", rootUrl);
            }
        }
        private string script = @"
            window.open('{0}','',
                'scrollbars=no,menubar=no,height=600,width=800,resizable=yes,toolbar=no,location=no,status=no');
        ";
        protected void OpenWindow(object sender, EventArgs e)
        {
            string page = string.Concat(
                  this.RootUrl, ((LinkButton)sender).CommandArgument);
            ///
            /// Check your condition
            ///
            bool myCondition = true;
            if (myCondition)
            {
                Page.ClientScript.RegisterClientScriptBlock(
                    this.GetType(),
                    this.GetType().Name,
                    string.Format(this.script, page),
                    true);
            }
        }        
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <asp:LinkButton 
            runat="server" 
            ID="lnkButton" 
            OnClick="OpenWindow" 
            Text="Open a Window" 
            CommandArgument="Tutorials/Rocky/Training.pdf" />
    </form>
</body>
</html>
 

Read more panel like facebook wall : Asp.Net


Demo:

To simulate FaceBook exactly, and extend the html inside a rendered page we can use AJAX,  JQuery,  Generic handler and a very simple web control.
Here is a sample that I had a play with
PS: Web control been hosted in a assembly called Active.Web.UI.Controls. You must host your web controls in appropriate place and add a reference accordingly

Web Control and Domain Objects

public class PostView : WebControl
{
    public Post Post { get; set; }
    public PostView()
    {
        Post = new Post();
    }
    public override void RenderBeginTag(HtmlTextWriter writer)
    {
        writer.Write(string.Format("<div class=\"{0}\">", this.GetType().Name));
    }
    protected override void RenderContents(HtmlTextWriter writer)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat(
                "<div class=\"Header\"><h3>{0}</h3></div>", this.Post.Title);
        sb.AppendFormat(
                "<div class=\"Content\"><p>{0}</p></div>", this.Post.Content);
        writer.Write(sb.ToString());
    }
    public override void RenderEndTag(HtmlTextWriter writer)
    {
        writer.Write("</div>");
    }
}

[Serializable]
public class Post
{
    public string Title { get; set; }
    public string Content { get; set; }
}
 
[Serializable]
public class Posts : List<Post>
{
    public Posts(string postId)
    {
        for (int i = 0; i < 25; i++)
        this.Add(new Post() { 
        Title = string.Format("Post {0}",(i + 1)), 
        Content = @"There are important differences between plain text files
        created by a text editor, and document files created by word processors
        such as Microsoft Word, WordPerfect, or OpenOffice.org. Briefly: A plain
        text file is represented and edited by showing all the characters as they
        are present in the file. The only characters usable for 'mark-up' are the
        control characters of the used character set; in practice this is newline, 
        tab and formfeed. The most commonly used character set is ASCII, 
        especially recently, as plain text files are more used for programming and 
        configuration and less frequently used for documentation than in the past. 
        Documents created by a word processor generally contain fileformat- 
        specific ""control characters"" beyond what is defined in the character 
        set. These enable functions like bold, italic, fonts, columns, tables, 
        etc. These and other common page formatting symbols were once associated 
        only with desktop publishing but are now commonplace in the simplest word 
        processor.Word processors can usually edit a plain text file and save in 
        the plain text file format. However one must take care to tell the program 
        that this is what is wanted. This is especially important in cases such as 
        source code, HTML, and configuration and control files. Otherwise the file 
        will contain those ""special characters"" unique to the word processor's 
        file format and will not be handled correctly by the utility the files 
        ere intended for." });
    }
}

Generic Hander - Named PostHandler.ashx

public class PostHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        int limit = int.Parse(context.Request.QueryString.Get("uBound"));
        string postId = context.Request.QueryString.Get("postId");
        Posts posts = new Posts(postId);
        StringBuilder sb = new StringBuilder();
        if (limit > 5)
        {
            sb.AppendFormat("::{0};", limit + 5 > posts.Count ? false : true);
            for (int i = limit - 5; i < limit; i++)
            {
                StringBuilder s = new StringBuilder();
                StringWriter tw = new StringWriter(s);
                HtmlTextWriter htw = new HtmlTextWriter(tw);
                (new PostView() { Post = posts[i] }).RenderControl(htw);
                sb.Append(s.ToString());
            }
        }
        context.Response.Write(sb.ToString());
    }
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

TestPage

<%@ Page Language="C#" AutoEventWireup="true"  %>
<%@ Import Namespace="Active.Web.UI.Controls" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Test Page</title>
    <script src="Scripts/jquery-1.4.1.min.js" 
            type="text/javascript" language="javascript"></script>
    <script runat="server">
        private string postId = "pid1234556";
        private string startupScript = @"
            var limit = 5;
            function ShowMorePosts() {{
                limit = limit + 5;
                $.ajax({{
                    url: 'Handlers/PostHandler.ashx?uBound=' + limit + ""&postId={0}"",
                    success: function (data) {{
                        if (data.match(""^"" + ""::True;"") 
                           != ""::True;"") $("".ShowMorePosts"").remove();
                        data = data.replace(/::true;/i, """");
                        data = data.replace(/::false;/i, """");
                        $("".PostList"").append(data);
                    }}
                }});
            }}
        ";
        protected override void OnInit(EventArgs e)
        {
            Posts posts = new Posts(this.postId);
            base.OnInit(e);
            for (int i = 0; i < 5 && i < posts.Count; i++)
                this.pnlPostList.Controls.Add(new PostView() { Post = posts[i] });
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.Page.ClientScript.RegisterStartupScript(
                       this.GetType(), this.GetType().Name,
                       string.Format(this.startupScript, this.postId), true);
        }
    </script>
</head>
<body>
    Test Page
    <form runat="server" id="form1">
        <asp:Panel runat="server" ID="pnlPostList" CssClass="PostList" />
        <a href="javascript:ShowMorePosts()" 
              title="Show More Posts" 
              class="ShowMorePosts">Show More Posts</a>
    </form>
</body>
</html>
 
 
 
 
 
 

Friday, January 22, 2010

Root URL property for Asp.net Web Applications

public string RootUrl
{
    get
    {
        Uri requestUri = Context.Request.Url;
        HttpRequest request = Context.Request;
        string rootUrl = string.Format("{0}{1}{2}{3}{4}",
            requestUri.Scheme,
            Uri.SchemeDelimiter,
            requestUri.Host,
            requestUri.IsDefaultPort ? string.Empty : string.Format(":{0}", requestUri.Port),
            request.ApplicationPath);
        return rootUrl.EndsWith("/") ? rootUrl : string.Format("{0}/", rootUrl);
    }
}

Wednesday, July 01, 2009

Generic Serialization Method - Microsoft C#.NET

using System.Xml.Serialization;
using System.Text;
public class SerializeManager
{
    public static XmlDocument Serialize(Type type, Object source)
    {
        MemoryStream stream = null;
        TextWriter writer = null;
        XmlDocument document = null;
        try
        {
            stream = new MemoryStream();
            writer = new StreamWriter(stream, Encoding.Unicode);
            XmlSerializer serializer = new XmlSerializer(type);
            serializer.Serialize(writer, source);
            int count = (int)stream.Length;
            byte[] array = new byte[count];
            stream.Seek(0, SeekOrigin.Begin);
            stream.Read(array, 0, count);
            UnicodeEncoding utf = new UnicodeEncoding();
            document = new XmlDocument();
            document.LoadXml(utf.GetString(array).Trim());
        }
        catch 
        {
            throw;
        }
        finally
        {
            if (stream != null) stream.Close();
            if (writer != null) writer.Close();
        }
        return document;
    }
}

Generic Clone Method C#.NET

Using reflection, this method copies each property of the source object to target object.

public virtual void Clone(Object source)
{
    if (source == null)
        throw new ArgumentNullException("Source");
    if (source.GetType() != this.GetType())
        throw new ArgumentException("Type Mismatch");
    foreach (PropertyInfo p in source.GetType().GetProperties())
        if (p.CanRead && p.CanWrite)
            p.SetValue(this, p.GetValue(source, null), null);
}

Wednesday, May 06, 2009

CSS Element selectors [pattern matching] - Cascade Style Sheet Syntax (CSS Syntax)

PatternMeaningDescribed in section
*Matches any element.Universal selector
EMatches any E element (i.e., an element of type E).Type selectors
E FMatches any F element that is a descendant of an E element.Descendant selectors
E > FMatches any F element that is a child of an element E.Child selectors
E:first-childMatches element E when E is the first child of its parent. The :first-child pseudo-class
E:link
E:visited
Matches element E if E is the source anchor of a hyperlink of which the target is not yet visited (:link) or already visited (:visited). The link pseudo-classes
E:active
E:hover
E:focus
Matches E during certain user actions.The dynamic pseudo-classes
E:lang(c) Matches element of type E if it is in (human) language c (the document language specifies how language is determined).The :lang() pseudo-class
E + FMatches any F element immediately preceded by a sibling element E.Adjacent selectors
E[foo]Matches any E element with the "foo" attribute set (whatever the value).Attribute selectors
E[foo="warning"]Matches any E element whose "foo" attribute value is exactly equal to "warning".Attribute selectors
E[foo~="warning"]Matches any E element whose "foo" attribute value is a list of space-separated values, one of which is exactly equal to "warning".Attribute selectors
E[lang|="en"]Matches any E element whose "lang" attribute has a hyphen-separated list of values beginning (from the left) with "en".Attribute selectors
DIV.warningLanguage specific. (In HTML, the same as DIV[class~="warning"].)Class selectors
E#myidMatches any E element with ID equal to "myid".ID selectors

Reference: W3C CSS Guidlines (Section 5: Selectors)

Thursday, April 23, 2009

CLRProfiler (CLR Profiler) waiting for application to start common language runtime - .NET Runtime


Symptom: When you start an application using CLR profiler, it always says [waiting for application to start common language runtime] and wait forever

Resolution

  1. Most probably you may be using CLR Profiler 1.1 to profile .NET 2.0 Application. Download CLR Profiler 2.0 from the here

  2. If it is VISTA or Windows XP, may be CLR Profiler doesn't have enough permissions to run. Try running CLR Profiler as an Administrator.
    Right Click on the CLRProfiler.exe -> Run as -> Administrator

Wednesday, April 22, 2009

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding – Microsoft ADO.NET


Symptom: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

Resolution:

  1. SqlConnection: If this happen when tries to connecting to SQL Server, then try increasing the timeout of the connection
    Connection String: server=Server;database=Database;uid=Uid;pwd=Pwd;timeout=600 (ConnectionTimeout is read-only)
  2. SqlCommand: More interestingly if you manage to connect successfully and although you set a fat timeout value to your connection command object does not inherit the timeout from its connection. It uses its own timeout value. More logically ConnectionTimeout and CommandTimeout.   
    So increase the timeout of the command, which is not read-only like SQLConnection

    command.CommandTimeot = 600 (set to 10 minutes)  

Reference: ASP.NET Forums

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...