Monday, June 14, 2010

How to load UserControl with parameters. LoadControl("VirtualPath", p1, p2) - Asp.net

This article demonstrate how to load a user control with constructor parameters in the LoadControl method. However we have implemented a method which accepts VirtualPath and n number of parameters.

Please review example below:

<%@ Page Language="C#" %>
<html>
<head id="Head1" runat="server">
    <script runat="server">
        public UserControl LoadControl(string UserControlPath, 
                params object[] constructorParameters)
        {
            List<Type> constParamTypes = new List<Type>();
            foreach (object constParam in constructorParameters)
                constParamTypes.Add(constParam.GetType());
            UserControl ctl = Page.LoadControl(UserControlPath) as UserControl;
            ConstructorInfo constructor = ctl.GetType()
                .BaseType.GetConstructor(constParamTypes.ToArray());
            if (constructor == null)
                throw new MemberAccessException("The requested constructor was not found on : " 
                    + ctl.GetType().BaseType.ToString());
            else
                constructor.Invoke(ctl, constructorParameters);
            return ctl;
        }
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            List<Employee> employees = new List<Employee>();
            if (!this.IsPostBack)
                for (int i = 0; i < 10; i++)
                    employees.Add(new Employee() { Id = "Emp" + i, Name = "Employee" + i });
            List<object> parameters = new List<object>();
            this.phUserControl.Controls.Add(this.LoadControl("~/UserControls/ActiveUserControl.ascx", 
                employees, "Existing Employees"));
        }
        protected override void OnLoad(EventArgs e)
        {
            this.EnsureChildControls();
            base.OnLoad(e);
            if (!this.IsPostBack)
                this.phUserControl.DataBind();
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <asp:PlaceHolder runat="server" ID="phUserControl"></asp:PlaceHolder>
    </form>
</body>
</html>

User Control

Markup:

<%@ Control Language="C#" AutoEventWireup="true" 
    CodeBehind="ActiveUserControl.ascx.cs" 
    Inherits="ActiveTest.UserControls.ActiveUserControl" %>
<div>
    <h1><asp:Label runat="server" ID="lblTitle" /></h1>
    <hr />
    <asp:GridView runat="server" ID="grvEmployees" AutoGenerateColumns="false">
        <Columns>
            <asp:TemplateField>
                <ItemTemplate>
                    <asp:Label runat="server" ID="lblId" Text='<%# Eval("Id") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField>
                <ItemTemplate>
                    <asp:TextBox runat="server" ID="txtName" Text='<%# Eval("Name") %>'></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
</div>

Code:

namespace ActiveTest.UserControls
{
    [ParseChildren(true)]
    public partial class ActiveUserControl : UserControl
    {
        public List<Employee> Employees
        {
            get { return (List<Employee>)(ViewState["Employees"] ?? (ViewState["Employees"] = new List<Employee>())); }
            set { ViewState["Employees"] = value; }
        }
        public string Title { getset; }
        public ActiveUserControl() { }
        public ActiveUserControl(List<Employee> employees, string title)
        {
            this.Employees = employees;
            this.Title = title;
        }
        public override void DataBind()
        {
            this.lblTitle.Text = this.Title;
            this.grvEmployees.DataSource = this.Employees;
            this.grvEmployees.DataBind();
        }
    }
 
    [Serializable]
    public class Employee
    {
        public string Id { getset; }
        public string Name { getset; }
    }
}

Sunday, June 13, 2010

How to find the control which caused a postback (Part 1 : Outside the event handler) - Asp.net

This article demonstrate how to find the control which cause a postback of a page outside the event handler. This code snippest cover
  1. Button
  2. Link Button
  3. TextBox
  4. Dropdown List
  5. Check Box
  6. Radio Button
Please note: When you try to find the clicked asp.net button, you have to turn off submit bebaviour to cuase a __doPostBack call
    Example

    <%@ Page Language="C#" %>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <script runat="server"> 
            protected override void OnLoad(EventArgs e)
            {
                if (this.IsPostBack)
                {
                    string uniqueId = this.Request.Form["__EVENTTARGET"];
                    if (!string.IsNullOrEmpty(uniqueId))
                    {
                        string[] parts = uniqueId.Split("$".ToCharArray());
                        string id = parts[parts.Length - 1];
                        Control ctrl = this.FindControl(id);
                        if (this.pnlPostbackDetails.Visible = ctrl != null)
                            this.lblControl.Text = string.Format(
                                "Type: {0} , Id: {1}", ctrl.GetType().Name, id);
                    }
                }
                base.OnLoad(e);
            }        
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Panel runat="server" ID="pnlContainer">
                <asp:Button 
                    runat="server" 
                    ID="btnPostabck" 
                    Text="Postback" 
                    UseSubmitBehavior="false" />
                <asp:LinkButton runat="server" ID="lnkPostback" Text="Postback" />
                <asp:TextBox runat="server" ID="txtName" AutoPostBack="true" />
                <asp:DropDownList runat="server" ID="ddlCountries" AutoPostBack="true">
                    <asp:ListItem>Select</asp:ListItem>
                    <asp:ListItem>SL (Sri Lanka)</asp:ListItem>
                    <asp:ListItem>UK (United Kingdom)</asp:ListItem>
                    <asp:ListItem>US (United States)</asp:ListItem>
                </asp:DropDownList>
                <asp:RadioButton 
                    runat="server" 
                    ID="rbPostback" 
                    Text="Postback" 
                    AutoPostBack="true" />
                <asp:CheckBox 
                    runat="server" 
                    ID="chkPostback" 
                    Text="Postback" 
                    AutoPostBack="true" />
            </asp:Panel>
            <hr />
            <asp:Panel runat="server" ID="pnlPostbackDetails" Visible="false">
                Postback Control Details: <asp:Label runat="server" ID="lblControl" />
            </asp:Panel>
        </div>
        </form>
    </body>
    </html>
     
     
     
     
     
     

    Tuesday, June 08, 2010

    How to access controls with in different Content Place Holders

    Sometimes it may necessary to access controls with in differnt Content Place Holders in the page. Solution is prefix Content Place Holder id with '$' control name.
    Control control = this.FindControl("FooterPlaceHolder$txtSearch");

    Example:

    <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
                <asp:SqlDataSource
                    id="SqlDataSource1"
                    runat="server"
                    ConnectionString="<%$ ConnectionStrings:ActiveConnectionString%>"
                    SelectCommand="SELECT * FROM dbo.Country"
                    FilterExpression="Name='{0}'">
                    <FilterParameters>
                        <asp:ControlParameter 
                          Name="Name"
                          ControlID="FooterContent$txtSearch" 
                          PropertyName="Text"/>
                    </FilterParameters>
                </asp:SqlDataSource>
        
    </asp:Content>
    <asp:Content ID="FooterContent" runat="server" ContentPlaceHolderID="FooterContent">
        <asp:TextBox runat="server" ID="txtSearch" />
    </asp:Content>

    Monday, June 07, 2010

    How to read value with in a external web page

    Although it is not adviable, sometimes it might need to read some specific text with in external webpages as information extration. This post domonstrate how to read views within given video URL either YouTube or MetaCafe

    string youTubeMarker = "<strong class=\"watch-view-count\">";
    string metaCafeMarker = "<li>Views: <strong>";
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        ///
        /// I explan this using hard corded value
        /// But in real world please get this form your relevent textbox
        /// url = this.txtUrl.Text;
        /// You may not call this in page load
        /// But you may call this code in PostVideoLink event handler
        ///
        string url = "http://www.youtube.com/watch?v=3Kk-yZ7VpeA";
        string views = this.GetViews(url);
        Response.Write(string.Format("YouTube video views: {0}", views));
        url = "http://www.metacafe.com/watch/yt-ByGgMeQSK8Y
        /asp_net_tutorial_master_pages_site_navigation_part1/";
        views = this.GetViews(url);
        Response.Write(string.Format("MetaCafe video views: {0}", views));
    }
    protected void PostVideoLink(object sender, EventArgs e)
    {
    }
    private string GetViews(string url)
    {
        string marker = string.Empty;
        if (url.Contains("www.youtube.com"))
            marker = this.youTubeMarker;
        else if (url.Contains("www.metacafe.com"))
            marker = this.metaCafeMarker;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        StreamReader sr = new StreamReader(request.GetResponse().GetResponseStream());
        if(string.IsNullOrEmpty(marker)) return string.Empty;
        string html = sr.ReadToEnd();
        int lb = html.IndexOf(marker) + marker.Length;
        int ub = html.IndexOf("<", lb);
        string views = html.Substring(lb, ub - lb);
        return views;
    }

    Saturday, June 05, 2010

    How does .Net Framework track Postback values : Asp.Net

    When page life cycle executes, for all controls in a page, if a control implements IPostBackDataHandler interface .net framwork invokes, IPostBackDataHandler's LoadPostData(string postKey, NameValueCollection postCollection)

    public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
    {
        ///
        /// Process your data here
        ///
        return false;
    }

    postCollection:
    Is a NameValueCollection which consist of all input filelds present in the page along with their values agaisnt corrosponding names.
    • ctrl00$txtFirstName - FirstName
    • ctrl00$txtSurname - Surname
    • ctrl00$txtAddress - Address
    Remember .net framwork use a format of ctl00_txtName as the id of the dom element. (.net control.ClientID) and exactly the same but separater is $ for name, ctrl00$txtName. (.net control UniqueID)
    postKey
    Is the name of the corresponding control. So easyly we can retrive the value of the input field like String postedValue = postCollection[postDataKey];
    In terms of writting HTML, when you write a html, you cant just use Response.Write("<input..... ) but you can write a simple web-control (in your case checkbox) and add instance of your custom check box to the page. Unless the control get added to the page, page life cycle wont be able to do anyting with your control. For build a simple web-control you can just extend WebControl class in System.Web.UI and to handle postbacks you may implement IPostBackDataHandler interface as well.
    Example:

    CustomCheckBox cchkBox = new CustomCheckBox();
    this.Page.Controls.Add(cchkBox);

    This is a complete example of Custom Checkbox which has a hidden field to hold it's value.

    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public class CustomCheckBox : WebControl,
                                    IPostBackDataHandler,
                                    INamingContainer
    {
        public bool Checked
        {
            get
            {
                return (bool)(ViewState["Checked"] ?? (ViewState["Checked"] = false));
            }
     
            set
            {
                ViewState["Checked"] = value;
            }
        }
        public bool AutoPostBack { getset; }
        public event EventHandler CheckChanged;
        public string Label { getset; }
        public virtual bool LoadPostData(string postDataKey,
                                        NameValueCollection postCollection)
        {
            bool presentValue = this.Checked;
            String postedValue = postCollection[postDataKey];
            if (!presentValue.Equals(postedValue))
            {
                this.Checked = postedValue.Equals("on") ? true : false;
                return true;
            }
            return false;
        }
        public virtual void RaisePostDataChangedEvent()
        {
            OnCheckChanged(EventArgs.Empty);
        }
        protected virtual void OnCheckChanged(EventArgs e)
        {
            if (CheckChanged != null)
                CheckChanged(this, e);
        }
        protected override void Render(HtmlTextWriter output)
        {
            output.Write(string.Format("<input type='checkbox' {0}{1} />",
                this.Checked ? " checked='checked'" : string.Empty,
                this.AutoPostBack ? string.Format(
                    " onclick=\"javascript:__doPostBack('{0}','');\"",
                    this.UniqueID) :
                string.Empty));
            output.Write(string.Format("<span>{0}</span>"this.Label));
            output.Write(string.Format("<input type='hidden' value='{0}' id='{1}' name='{2}' />",
                this.Checked ? "off" : "on"this.ClientID, this.UniqueID));
        }
    }

    Friday, June 04, 2010

    How to post values to diffent page using HttpWebRequest : Asp.net

    Using Asp.net HttpWebRequest object we can post data to external page and get a HttpWebResponse

    string strId = "regid789654";
    string strName = "Charith";
    ASCIIEncoding encoding = new ASCIIEncoding();
    string postData = "userid=" + strId;
    postData += ("&username=" + strName);
    byte[] data = encoding.GetBytes(postData);
    HttpWebRequest request =
        (HttpWebRequest)WebRequest.Create("http://www.domain.com/cart.asp");
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = data.Length;
    Stream newStream = request.GetRequestStream();
    newStream.Write(data, 0, data.Length);
    newStream.Close();
     
    StreamReader sr = new StreamReader(request.GetResponse().GetResponseStream());
    string result = sr.ReadToEnd();
    sr.Close();

    Thursday, June 03, 2010

    How to find which page a IFRAME embeded in - Asp.net

    There are some common senarios where we need to find which page we are in and which domain the parent page belongs to. Specially when we work with banners and advertiesments this may be useful. However, this post demonstrates how to find domain and file name using round trip to client. But for the first request this parameters will not be available but from the second request onwards those parameters will be available to the code behind.

    <%@ Page Language="C#"  %>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title></title>
        <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript" language="javascript"></script>
        <script type="text/javascript" language="javascript">
            $(document).ready(function () {
                var url = parent.location.href.replace('http://''');
                if (url.search('.aspx?') != -1) url = url.split("?")[0];
                var location = window.location.href;
                if (location.search('page') == -1 && location.search('domain') == -1) {
                    var parts = url.split("/");
                    var d = parts[0];
                    if (parts.length > 1) {
                        var fileName = parts[parts.length - 1];
                        var p = fileName.split(".")[0];
                        window.location.href = location + "?page=" + p + "&domain=" + d;
                    }
                    else
                        window.location.href = location + "?domain=" + d;
                }
            });
        </script>
        <script runat="server">
            protected override void OnLoad(EventArgs e)
            {
                base.OnLoad(e);
                string source = this.Page.Request.QueryString.Get("page");
                string domain = this.Page.Request.QueryString.Get("domain");
                if (!string.IsNullOrEmpty(domain))
                {
                    ///
                    /// Use domain
                    ///
                }
                if (!string.IsNullOrEmpty(source))
                {
                    if (source.StartsWith("A"))
                    {
                        ///
                        /// A Group page
                        /// 
                    }
                    else if (source.StartsWith("B"))
                    {
                        ///
                        /// B Group page
                        ///
                    }
                }
            }       
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
            Test 
        </form>
    </body>
    </html>
     

    Hyperlink rewritting with anchor tags - Asp.net

    Idea is to rewrite all hyperlinks to have a anchor tag appended when you focus the page in to a anchor tag in a aspx page.In this senario, I have occupied a static anchor tag, but easyliy we can utilize this dynamically from query string

    <%@ Page Language="C#"  %>
    <html>
    <head id="Head1" runat="server">
        <title></title>
        <script language="javascript" type="text/javascript">
        </script>
        <script runat="server">
            protected override void Render(HtmlTextWriter writer)
            {
                string a = "C123456";
                StringBuilder sb = new StringBuilder();
                HtmlTextWriter htw = new HtmlTextWriter(new System.IO.StringWriter(sb));
                base.Render(htw);
                string html = sb.ToString();
                int lc = html.IndexOf("<a", 0);
                while (lc > 0)
                {
                    int lb = html.IndexOf("href=", lc) + 6;
                    int ub = html.IndexOf("\"", lb);
                    string link = html.Substring(lb, ub - lb);
                    if (!link.Contains("#"))
                    {
                        string newLink = string.Format("{0}#{1}", link, a);
                        html = html.Replace(link, newLink);
                    }
                    if (lc + 2 < html.Length)
                        lc = html.IndexOf("<a", lc + 2);
                    else lc = -1;
                }
                writer.Write(html);
            }
            protected void ShowSection(object sender, EventArgs e)
            {
                this.Response.Redirect("Test2.aspx#c2345"true);
            }        
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:Button runat="server" ID="btnPostback" 
                OnClick="ShowSection" Text="Show Section" />
            <asp:HyperLink runat="server" ID="HyperLink1" 
                NavigateUrl="~/Test1.aspx" Text="Normal Link" />        
            <asp:HyperLink runat="server" ID="HyperLink2" 
                NavigateUrl="~/Test2.aspx" Text="Normal Link" />
            <asp:HyperLink runat="server" ID="HyperLink3" 
                NavigateUrl="~/Test3.aspx" Text="Normal Link" />
            <asp:HyperLink runat="server" ID="HyperLink4" 
                NavigateUrl="~/Test4.aspx" Text="Normal Link" />
            <asp:HyperLink runat="server" ID="HyperLink5" 
                NavigateUrl="~/Test5.aspx" Text="Normal Link" />
        </form>
    </body>
    </html>

    Monday, May 31, 2010

    ASP.net and ATL Server debugging - IIS 7

    Cause:
    Error while trying to run project: Unable to start debugging on the web server. The server does not support debugging of ASP.NET or ATL Server applications. Run setup to install the Visual Studio .NET server components. If setup has been run, verify that a valid URL has been specified.


    You may also want to refer to the ASP.NET and ATL Server debugging topic in the online documentation. Would you like to disable future attempts to debug ASP.NET pages for this project?
    Posible reson is to have in-compatile web.config after converting asp.net 3.5 application to asp.net 4.0 application.

    Example: having modules and httpModules in the same web.config

    <configuration>
      ...
      <system.web>
        ...
        <httpModules>
          <add name="SEOModule"
             type="WebSphere.Ngate.SEOModule.SEOModule, WebSphere.Ngate.SEOModule" />
        </httpModules>
      </system.web>
      <system.webServer>
        <modules>
          <add name="SEOModule" preCondition="managedHandler"
             type="WebSphere.Ngate.SEOModule.SEOModule, WebSphere.Ngate.SEOModule" />
        </modules>
        ...
      </system.webServer>
    </configuration>

    Removing httpModules section will resolve the problem

    <configuration>
      ...
      <system.web>
        ...
      </system.web>
      <system.webServer>
        <modules>
          <add name="SEOModule" preCondition="managedHandler"
             type="WebSphere.Ngate.SEOModule.SEOModule, WebSphere.Ngate.SEOModule" />
        </modules>
        ...
      </system.webServer>
    </configuration>

    Wednesday, May 26, 2010

    Asp.net Dom Validation script : for custom validators

    //<script>
    var Page_DomValidationVer = "2";
    var Page_IsValid = true;
    var Page_BlockSubmit = false;
     
    function ValidatorUpdateDisplay(val) {
        if (typeof (val.display) == "string") {
            if (val.display == "None") {
                return;
            }
            if (val.display == "Dynamic") {
                val.style.display = val.isvalid ? "none" : "inline";
                return;
            }
        }
        val.style.visibility = val.isvalid ? "hidden" : "visible";
    }
     
    function ValidatorUpdateIsValid() {
        var i;
        for (i = 0; i < Page_Validators.length; i++) {
            if (!Page_Validators[i].isvalid) {
                Page_IsValid = false;
                return;
            }
        }
        Page_IsValid = true;
    }
     
    function ValidatorHookupControl(control, val) {
        if (typeof (control.Validators) == "undefined") {
            control.Validators = new Array;
            var ev = control.onchange;
            var func = new Function("ValidatorOnChange('" + control.id + "');");
            control.onchange = func;
        }
        control.Validators[control.Validators.length] = val;
    }
     
    function ValidatorGetValue(id) {
        var control;
        control = document.getElementById(id);
        if (typeof (control.value) == "string") {
            return control.value;
        }
        if (typeof (control.tagName) == "undefined" && typeof (control.length) == "number") {
            var j;
            for (j = 0; j < control.length; j++) {
                var inner = control[j];
                if (typeof (inner.value) == "string" && (inner.type != "radio" || inner.status == true)) {
                    return inner.value;
                }
            }
        }
        return "";
    }
     
    function Page_ClientValidate() {
        var i;
        for (i = 0; i < Page_Validators.length; i++) {
            ValidatorValidate(Page_Validators[i]);
        }
        ValidatorUpdateIsValid();
        Page_BlockSubmit = !Page_IsValid;
        return Page_IsValid;
    }
     
    function ValidatorCommonOnSubmit() {
        var returnValue = !Page_BlockSubmit;
        Page_BlockSubmit = false;
        return returnValue;
    }
     
    function ValidatorOnChange(controlID) {
        var cont = document.getElementById(controlID);
        var vals = cont.Validators;
        var i;
        for (i = 0; i < vals.length; i++) {
            ValidatorValidate(vals[i]);
        }
        ValidatorUpdateIsValid();
    }
     
    function ValidatorValidate(val) {
        val.isvalid = true;
        if (typeof (val.evalfunc) == "function") {
            val.isvalid = val.evalfunc(val);
        }
        ValidatorUpdateDisplay(val);
    }
     
    function ValidatorOnLoad() {
        if (typeof (Page_Validators) == "undefined")
            return;
     
        var i, val;
        for (i = 0; i < Page_Validators.length; i++) {
            val = Page_Validators[i];
            var evalFunction = val.getAttribute("evaluationfunction");
            if (typeof (evalFunction) == "string") {
                eval("val.evalfunc = " + evalFunction + ";");
            }
            var isValidAttribute = val.getAttribute("isvalid");
            if (typeof (isValidAttribute) == "string") {
                if (isValidAttribute == "False") {
                    val.isvalid = false;
                    Page_IsValid = false;
                }
                else {
                    val.isvalid = true;
                }
            } else {
                val.isvalid = true;
            }
            var controlToValidate = val.getAttribute("controltovalidate");
            if (typeof (controlToValidate) == "string") {
                ValidatorHookupControl(document.getElementById(controlToValidate), val);
            }
        }
        Page_ValidationActive = true;
    }
     
    function RegularExpressionValidatorEvaluateIsValid(val) {
        var value = ValidatorGetValue(val.getAttribute("controltovalidate"));
        if (value == "")
            return true;
        var rx = new RegExp(val.getAttribute("validationexpression"));
        var matches = rx.exec(value);
        return (matches != null && value == matches[0]);
    }
     
    function ValidatorTrim(s) {
        var m = s.match(/^\s*(.*\S)\s*$/);
        return (m == null) ? "" : m[1];
    }
     
    function RequiredFieldValidatorEvaluateIsValid(val) {
        return (ValidatorTrim(ValidatorGetValue(val.getAttribute("controltovalidate"))) 
            != ValidatorTrim(val.getAttribute("initialvalue")));
    }

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