Saturday, May 22, 2010

Resetable Panel Asp.Net - Reset all values to default values of child controls and nested panels.

Well, there is no reset method for asp.net panel by the time of this article. But certainly we can implement a reset method by extending functionalities of required controls.
PS: If this functionality is widely use I would implement something like this. But it is only for less then 10 controls don't walk on this root.
As asp.net is extensible, we can extend Label, Textbox to have DefaultValues property and a mechanism to on and off (LoadDefaultValue which is true by default) the feature so that we can use it like ordinary controls.
  1. Implement's key feature is an interface called IXControl 
  2. Which has three members. Namely string DefaultValues { get; set; }, bool LoadDefault { get; set; } and void Reset();
  3. All X Controls implement this interface. 
  4. Inside the Reset method of each control, call common helper method called ResetProperties passing parameters, this control and DefaultValues property.
  5. DefaultValues propety should be a list of comma seperated { PropertyName=ProperyValue } pairs. Example DefaultValues="Text=DefaultText;ForeColor=Red;BackColor=Blue;Visible=false ... N
  6. Inside ResetProperties we decode DefaultValues string using string split and populate PropertyValue list
  7. Then use Reflection to go through each property of control and if propety name matchs one of in the list, set the value of the property using PropertyInfo
  8. Inside the panel Reset method, we call ResetInteranl so it will hock up all the child controls. Call Reset method using IXControl interface determining if the child type is IXControl.
  9. There is a catch, we need to go to children only if control is not a XPanel. Because once we call the Reset of XPanel it know how to reset all of it's children by itself
Extended controls and IXPanel interface : PS I have hosted custom controls in a separate assembly called Active.Web.UI.Controls. So you might nedd to change to namespace and assembly to get this working accroding to your control location.

Code:
/// <summary>
/// ControlManager and PropertyValue classes
/// </summary>
 
public class ControlManager
{
    public static void ResetProperties(Control control, string defaultValues)
    {
        if (string.IsNullOrEmpty(defaultValues)) return;
        List<PropertyValue> pvs = new List<PropertyValue>();
        foreach (string pv in defaultValues.Split(";".ToCharArray()))
        {
            string[] s = pv.Split("=".ToCharArray());
            if (s.Length == 2 && !string.IsNullOrEmpty(s[0]))
                pvs.Add(new PropertyValue() { Property = s[0].Trim(), Value = s[1] });
        }
        foreach (PropertyInfo p in control.GetType().GetProperties())
        {
            PropertyValue pv = pvs.Find(x => x.Property.Equals(p.Name));
            if (pv != null)
            {
                if (p.PropertyType.Equals(typeof(string)))
                    p.SetValue(control, pv.Value, null);
                else if (p.PropertyType.Equals(typeof(Color)))
                {
                    try { p.SetValue(control, new ColorConverter().ConvertFromString(pv.Value), null); }
                    catch { }
                }
                else if (p.PropertyType.Equals(typeof(bool)))
                {
                    bool value;
                    if (bool.TryParse(pv.Value, out value))
                        p.SetValue(control, value, null);
                }
                ///
                /// You can extend this for any other criteria
                ///
            }
        }
    }
}
public class PropertyValue
{
    public string Property { getset; }
    public string Value { getset; }
}
 
/// <summary>
/// IXControl interface
/// </summary>
 
public interface IXControl
{
    string DefaultValues { getset; }
    bool LoadDefault { getset; }
    void Reset();
}
 
/// <summary>
/// XLabel 
/// </summary>
 
public class XLabel : LabelIXControl
{
    public string DefaultValues { getset; }
    public bool LoadDefault { getset; }
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        if (this.LoadDefault && !this.Page.IsPostBack) this.Reset();
    }
    public void Reset()
    {
        ControlManager.ResetProperties(thisthis.DefaultValues);
    }
}
 
/// <summary>
/// XTextbox
/// </summary>
 
public class XTextBox : TextBoxIXControl
{
    public string DefaultValues { getset; }
    public bool LoadDefault { getset; }
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        if (this.LoadDefault && !this.Page.IsPostBack) this.Reset();
    }
    public void Reset()
    {
        ControlManager.ResetProperties(thisthis.DefaultValues);
    }
}
 
/// <summary>
/// XPanel
/// </summary>
 
public class XPanel : PanelIXControl
{
    public string DefaultValues { getset; }
    public bool LoadDefault { getset; }
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        if (this.LoadDefault && !this.Page.IsPostBack) this.Reset();
    }
    public void Reset()
    {
        ControlManager.ResetProperties(thisthis.DefaultValues);
        this.ResetInternal(this.Controls);
    }
    private void ResetInternal(ControlCollection controlCollection)
    {
        foreach(Control control in controlCollection)
        {
            if (control is IXControl) ((IXControl)control).Reset();
            if (control.Controls.Count > 0 && !control.GetType().Equals(typeof(XPanel)))
                this.ResetInternal(control.Controls);
        }
    }
}

Markup:

<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Register Assembly="Active.Web.UI.Controls" Namespace="Active.Web.UI.Controls" TagPrefix="active" %>
<%@ Import Namespace="System.Drawing" %>
<!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="Head2" runat="server">
    <title>Reset Panel</title>
    <script runat="server">
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            for (int i = 0; i < 30; i++)
            {
                this.xpnlContainer.Controls.Add(
                    new XLabel() { DefaultValues = String.Format("Text={0};Visible=true;ForeColor=Red""Label " + i) });
                this.xpnlContainer.Controls.Add(
                    new XTextBox() { DefaultValues = String.Format("Text={0};Visible=true;BackColor=Blue""Textbox " + i) });
                XPanel panel =new XPanel() { BackColor = System.Drawing.Color.Red, Visible = false, DefaultValues = "Visible=true" };
                panel.Controls.Add(new XLabel() { Text = "Nested Label - Init", DefaultValues = "Text=Nested Label Default" });
                this.xpnlContainer.Controls.Add(panel);
            }
        }
        public void Reset(object sender, EventArgs e)
        {
            this.xpnlContainer.Reset();
        }        
    </script>
</head>
<body>
    <form id="form2" runat="server">
    <div>
        <active:XPanel runat="server" ID="xpnlContainer" />
        <asp:Button runat="server" ID="btnReset" Text="Reset" OnClick="Reset" />
        <asp:Button runat="server" ID="btnPostback" Text="Postback" />
    </div>
    </form>
</body>
</html>

Monday, May 17, 2010

How to build login session timeout prompt message using jQuery

ASP.Net forms authentication session renew its authentication ticket only when the total escape time exceeds the half of the configured timeout. Say for example if you have 20 minutes configured in the web.config.
  1. Login time : 2.00 pm – Authentication ticket created (Expire on 2.20 pm)
  2. Do a postback: 2.05 pm. Before 10 minutes, which is a half of the configured timeout – Authentication ticket will not get renewed (Expire on 2. 20 pm)
  3. Leave browser – no postbacks
  4. Do a postback: 2.12 pm. After 10 minutes, which is a half of the configured timeout – Authentication ticket will get renewed (Expire on 2.32 pm)
If you need to have a time out message in your web page, we have to use a java script function with a counter. When counter comes to a certain point, say 2 minutes before the actual forms time out show the timeout message. However according to above explanation there is no constant timeout value for the first half of the timeout. Therefore we have to calculate the timeout and pass it to the java script function on each postback.

Example:





Test page inherit from the page base:

public class PageBase : Page
{
    private string startUpStript = @"
        var timeout = ({0} * 60) - 10;
        var timeEscaped = 0;
        var timerTicks = 0;
        var showBefore = 30
        function CountDown() {{
            if (timeEscaped < timeout - showBefore) {{
                setTimeout(CountDown, 1000);
                timeEscaped++;
            }}
            else
                ShowTimer();
        }}
        function ShowTimer() {{
            $("".LoginTimeout"").fadeIn();
            DisplayTime();
        }}
        function DisplayTime() {{
            if (timerTicks < showBefore) {{
                $("".LoginTimeout .TimeoutMessage .Timeout"").text(showBefore - timerTicks);
                timerTicks++;
                setTimeout(DisplayTime, 1000);
            }}
            else ShowTimedOutMsg();
        }}
        function ShowTimedOutMsg() {{
            $("".LoginTimeout .TimeoutMessage"").fadeOut();
            $("".LoginTimeout .LoggedOutMessage"").fadeIn();
        }}
        $(document).ready(function () {{
            CountDown()
        }});
    ";
    public LoginTimeout LoginTimeout
    {
        get { return (LoginTimeout)Session["LoginTimeout"]; }
        set { Session["LoginTimeout"] = value; }
    }
    public override void ProcessRequest(HttpContext context)
    {
        base.ProcessRequest(context);
        if (context.User != null && context.User.Identity.IsAuthenticated)
        {
            FormsIdentity identity = this.User.Identity as FormsIdentity;
            FormsAuthenticationTicket ticket = identity.Ticket;
            if (this.LoginTimeout == null || this.LoginTimeout.IssuedTime != ticket.IssueDate)
            {
                this.LoginTimeout = new LoginTimeout()
                {
                    IssuedTime = ticket.IssueDate,
                    TimeOut = FormsAuthentication.Timeout
                };
            }
            else
            {
                TimeSpan adjustment = DateTime.Now - this.LoginTimeout.IssuedTime;
                this.LoginTimeout.TimeOut = FormsAuthentication.Timeout - adjustment;
            }
        }
    }
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        if (this.LoginTimeout != null)
            this.Page.ClientScript.RegisterClientScriptBlock(
                this.GetType(),
                this.GetType().Name,
                string.Format(this.startUpStript, this.LoginTimeout.TimeOut.Minutes),
                true);
    }
 
}
public class LoginTimeout
{
    public DateTime IssuedTime { getset; }
    public TimeSpan TimeOut { getset; }
}

Test page markup:

<%@ Page Language="C#" AutoEventWireup="true"
     CodeBehind="Test.aspx.cs" Inherits="ActiveTest.Test" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Test Page</title>
    <style type="text/css">
        body { font-family:Tahomafont-size:11px; }
        p { padding:0margin:0; }
        .LoginTimeoutdisplay:none; 
                       padding:10px; 
                       background-color:#ffbd8c; 
                       height:15px; 
                       border:dotted 1px #f57313; 
                       text-align:center; 
                       width:300px; }
        .LoginTimeout .LoggedOutMessage,
        .LoginTimeout .TimeoutMessage { position:absolute; }
        .LoginTimeout .LoggedOutMessage { display:none; }
    </style>
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript" language="javascript"></script>
</head>
<body>
    Test Page
    <form method="get" action="Page2.html">
        <div class="LoginTimeout">
            <div class="TimeoutMessage">
                <p>Your login session will timeout in <strong>
                <span class="Timeout"></span></strong> seconds</p></div>
            <div class="LoggedOutMessage">
                <p>Your login sesson has timed out. You need to <a href="Login.aspx">
                login again</a></p></div>
        </div>
    </form>
</body>
</html>

Test page code behind:

namespace ActiveTest
{
    public partial class Test : PageBase
    {
 
    }
} 

Reference: Understanding the Forms Authentication Ticket and Cookie

Saturday, May 15, 2010

Syntax Highlighter : Embed code examples in blog posts

Syntax Highlighter is a widely used (Asp.net forums) code/markup embedding script (tool), which supports widely used blog engines including blogspot and wordpress. 

Configuration:

Blogspot:
Settings -> Layout -> Edit Html

Inside the html include following links and java script inside your  head closing tag </head>

<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' 
    rel='stylesheet' type='text/css'/> 
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' 
    rel='stylesheet' type='text/css'/> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' 
    type='text/javascript'></script> 
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' 
    type='text/javascript'></script> 
 
<script language='javascript'>
    SyntaxHighlighter.config.bloggerMode = true;
    SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
    SyntaxHighlighter.all();
</script>

Syntax Highlighter supports vast range of programming and markup syntax as listed below.
  1. HTML
  2. C++ (CPP)
  3. C# (CSharp)
  4. CSS
  5. Java
  6. JScript (javascript)
  7. PHP
  8. Python
  9. Ruby
  10. SQL
  11. VB
  12. XML
  13. Perl
Use with in your post
  1. Click on 'Edit HTML' tab (blogger) 
  2. Wrap your code with <pre> tag as listed below

<pre class="brush:CSharp">
      public void MyMethod()
      {
          ///
          /// Example method
          ///
      }
</pre> 


Available Options

<pre class="brush:html"></pre>
<pre class="brush:cpp"></pre> 
<pre class="brush:csharp"></pre>
<pre class="brush:css"></pre>
<pre class="brush:java"></pre> 
<pre class="brush:jscript"></pre>
<pre class="brush:php"></pre> 
<pre class="brush:python"></pre>
<pre class="brush:ruby"></pre> 
<pre class="brush:sql"></pre>
<pre class="brush:vb"></pre> 
<pre class="brush:xml"></pre>
<pre class="brush:perl"></pre> 

Links and references
  1. Syntax Highlighter
  2. Download
  3. Visit downlaod page
  4. Use online

Wednesday, April 28, 2010

Learn Microsoft Siverlight

  1. Getting Started with Microsoft Silverlight
  2. Silverlight screencasts and Traning Videos
  3. Learn Expression Blend and Design

Unable to start debugging on the web server. The server committed a protocol violation. Section=ResponseStatusLine

When try to debug in IIS, visual studio returns following above error:

It was interesting notice that (thanks for following post by Martin) Skype is already occupy the port 80. So IIS is unable to start.

Please un-tick

Skype -> Tools -> Options -> Advanced -> Connection:

Use port 80 and 443 as alternatives for incoming connections - Check box

Reference: The server committed a protocol violation

Could not download the Silverlight application. Check web server settings

Unhandled Error in Silverlight Application Code: 2104

Category: InitializeError

Frequently occures when try to host a silverlight application in a web server which does have following MIME type

File Name Extension: .xap

MIME Type: applicaton/x-silverlight-app

Reference: Register XAP file extention in IIS

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 { getset; }
 
        [DefaultValue("ActiveTextBoxCssClass")]
        [Bindable(true)]
        public string TextBoxCssClass { getset; }
 
        [DefaultValue("ActiveTreeViewCssClass")]
        [Bindable(true)]
        public string TreeViewCssClass { getset; }
 
        [DefaultValue("")]
        [Bindable(true)]
        public string SelectedDirectoryName { getset; }
 
        [DefaultValue(false)]
        [Bindable(true)]
        public bool ShowFullPath { getset; }
 
        #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 != nullthis.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 { getset; }
    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>
 

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