Web Control Rendering Example

This example shows how to create a control named MailLink that creates an email link in a Web page by rendering a hyperlink (<a>) element with a mailto: URI. The control demonstrates the tasks that you will generally perform when rendering a control that derives from the WebControl class.

The MailLink control exposes an Email property for the email address and a Text property for the text to display on the hyperlink. A page developer can set these properties as shown by the highlighted text:

<aspSample:MailLink id="maillink1" Email="someone@example.com" 
    runat="server">
  Mail Webmaster
</aspSample:MailLink> 

If the markup rendered by the control is viewed on the client, it will appear as the following:

<a id="maillink1" href="mailto:someone@example.com">
  Mail Webmaster
</a>

The behavior of a mailto: URI can be different in different browsers. In Internet Explorer, when a user clicks a mailto: hyperlink, the browser launches the user's default email client (if the email client is installed and compatible with the browser). The code for the MailLink control is described in the "Code Discussion" section later in this topic.

' MailLink.vb 
Option Strict On 
Imports System
Imports System.ComponentModel
Imports System.Security
Imports System.Security.Permissions
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace Samples.AspNet.VB.Controls
    < _
    AspNetHostingPermission(SecurityAction.Demand, _
        Level:=AspNetHostingPermissionLevel.Minimal), _
    AspNetHostingPermission(SecurityAction.InheritanceDemand, _
        Level:=AspNetHostingPermissionLevel.Minimal), _
    DefaultProperty("Email"), _
    ParseChildren(True, "Text"), _
    ToolboxData("<{0}:MailLink runat=""server""> </{0}:MailLink>") _
    > _
    Public Class MailLink
        Inherits WebControl
        < _
        Bindable(True), _
        Category("Appearance"), _
        DefaultValue(""), _
        Description("The e-mail address.") _
        > _
        Public Overridable Property Email() As String 
            Get 
                Dim s As String = CStr(ViewState("Email"))
                If s Is Nothing Then s = String.Empty
                Return s
            End Get 
            Set(ByVal value As String)
                ViewState("Email") = value
            End Set 
        End Property

        < _
        Bindable(True), _
        Category("Appearance"), _
        DefaultValue(""), _
        Description("The text to display on the link."), _
        Localizable(True), _
        PersistenceMode(PersistenceMode.InnerDefaultProperty) _
        > _
        Public Overridable Property Text() As String 
            Get 
                Dim s As String = CStr(ViewState("Text"))
                If s Is Nothing Then s = String.Empty
                Return s
            End Get 
            Set(ByVal value As String)
                ViewState("Text") = value
            End Set 
        End Property 

        Protected Overrides ReadOnly Property TagKey() _
            As HtmlTextWriterTag
            Get 
                Return HtmlTextWriterTag.A
            End Get 
        End Property 


        Protected Overrides Sub AddAttributesToRender( _
            ByVal writer As HtmlTextWriter)
            MyBase.AddAttributesToRender(writer)
            writer.AddAttribute(HtmlTextWriterAttribute.Href, _
                "mailto:" & Email)
        End Sub 

        Protected Overrides Sub RenderContents( _
            ByVal writer As HtmlTextWriter)
            If (Text = String.Empty) Then
                Text = Email
            End If
            writer.WriteEncodedText(Text)
        End Sub 

    End Class 
End Namespace
// MailLink.cs 
using System;
using System.ComponentModel;
using System.Security;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Samples.AspNet.CS.Controls
{
    [
    AspNetHostingPermission(SecurityAction.Demand,
        Level = AspNetHostingPermissionLevel.Minimal),
    AspNetHostingPermission(SecurityAction.InheritanceDemand, 
        Level=AspNetHostingPermissionLevel.Minimal),
    DefaultProperty("Email"),
    ParseChildren(true, "Text"),
    ToolboxData("<{0}:MailLink runat=\"server\"> </{0}:MailLink>")
    ]
    public class MailLink : WebControl
    {
        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(""),
        Description("The e-mail address.")
        ]
        public virtual string Email
        {
            get
            {
                string s = (string)ViewState["Email"];
                return (s == null) ? String.Empty : s;
            }
            set
            {
                ViewState["Email"] = value;
            }
        }

        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(""),
        Description("The text to display on the link."),
        Localizable(true),
        PersistenceMode(PersistenceMode.InnerDefaultProperty)
        ]
        public virtual string Text
        {
            get
            {
                string s = (string)ViewState["Text"];
                return (s == null) ? String.Empty : s;
            }
            set
            {
                ViewState["Text"] = value;
            }
        }

        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.A;
            }
        }

        protected override void AddAttributesToRender(
            HtmlTextWriter writer)
        {
            base.AddAttributesToRender(writer);
            writer.AddAttribute(HtmlTextWriterAttribute.Href, 
                "mailto:" + Email);
        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
            if (Text == String.Empty)
            {
                Text = Email;
            }
            writer.WriteEncodedText(Text);
        }
    }
}

Code Discussion

The MailLink control example illustrates these tasks:

  • Rendering a non-default element for the control.

  • Rendering attributes on the control's opening tag.

  • Rendering content within the control's tags.

The MailLink control overrides the TagKey property to render an <a> element instead of the default <span> element rendered by the WebControl class. You should override the TagKey property if the element you want to render is a member of the HtmlTextWriterTag enumeration. Many common HTML element tags are mapped to values of the HtmlTextWriterTag enumeration. For example, HtmlTextWriterTag.A corresponds to an <a> element and HtmlTextWriterTag.Table corresponds to a <table> element. If the element you want to render is not represented by a member of the HtmlTextWriterTag enumeration, override the TagName property and return the string to render as the element.

The MailLink control overrides the following rendering methods of the WebControl class:

The MailLink control also demonstrates inner text persistence. MailLink enables a page developer to specify the Text property within the control's tags, as shown by the highlighted text:

<aspSample:MailLink id="maillink1" Email="someone@example.com" 
    runat="server">
  Mail Webmaster
</aspSample:MailLink>

Inner persistence is in contrast to default persistence on the control's opening tag, as in this example:

<aspSample:MailLink Text="Mail Webmaster" runat="server" />

Default persistence and inner persistence are functionally identical. To enable inner persistence, MailLink is marked with the ParseChildren(true, "Text") attribute. The first argument of the ParseChildrenAttribute constructor specifies that the page parser should parse content within the control's tags as properties rather than as child controls. The second argument provides the name of the inner default property of the control (in this example, Text). When the ParseChildrenAttribute constructor is called with these two parameters, the content within the control's tags must correspond to the inner default property. The PersistenceMode(PersistenceMode.InnerDefaultProperty) attribute on the Text property specifies that a visual designer should serialize the property as inner content within the control's tags.

WebControl is marked with the PersistChildren(false) and ParseChildren(true) attributes, which govern design-time and parse-time property persistence. These are inherited with the control and need to be applied only if you want to change the inherited settings. The PersistChildrenAttribute tells the designer whether the child controls of a server control should be persisted as nested inner controls. The argument false indicates that inner content corresponds to properties and not to child controls. The ParseChildrenAttribute was described in the previous paragraph. If the design-time and parse-time persistence of the WebControl class is appropriate for your control, you do not have to override the PersistChildrenAttribute and ParseChildrenAttribute attributes inherited from WebControl.

The following example shows an ASP.NET Web page (.aspx file) that uses the MailLink control.

<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
  <title>MailLink test page</title>
</head>
<body>
  <form id="Form1" runat="server">
    <aspSample:MailLink id="maillink1" Font-Bold="true" 
      ForeColor="Green" Email="someone@example.com" runat="server">
      Mail Webmaster
    </aspSample:MailLink>
  </form>
</body>
</html>
<%@ page language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
  <title>MailLink test page</title>
</head>
<body>
  <form id="Form1" runat="server">
    <aspSample:MailLink id="maillink1" Font-Bold="true" 
      ForeColor="Green" Email="someone@example.com" runat="server">
      Mail Webmaster
    </aspSample:MailLink>
  </form>
</body>
</html>

Building and Using the Example

For information about building the control and using it in a page, see Building the Custom Server Control Examples.

See Also

Other Resources

Developing Custom ASP.NET Server Controls