Ejemplo de representación de controles Web

Actualización: noviembre 2007

En este ejemplo se muestra cómo crear un control denominado MailLink quecrea un vínculo de correo electrónico en una página Web y representa un elemento de hipervínculo (un elemento a) con un identificador URI mailto:. Este control muestra las tareas que deberá realizar normalmente al representar un control derivado de la clase WebControl.

El control MailLink expone una propiedad Email para la dirección de correo electrónico y una propiedad Text para el texto que se va a mostrar en el hipervínculo. Un desarrollador de páginas puede establecer el valor de estas propiedades tal y como muestra el texto resaltado:

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

Si el formato representado por el control se visualiza en el cliente, aparecerá de la siguiente manera:

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

El comportamiento de un identificador URI mailto: puede ser distinto según el explorador. En Internet Explorer, al hacer clic en un hipervínculo mailto:, el explorador inicia el cliente de correo electrónico predeterminado del usuario (si el cliente de correo electrónico está instalado y es compatible con el explorador). El código del control MailLink se describe en la sección "Descripción del código" más adelante en este tema.

' 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);
        }
    }
}

Descripción del código

En el ejemplo del control MailLink se muestran estas tareas:

  • Representación de un elemento no predeterminado para el control.

  • Representación de los atributos en la etiqueta de apertura del control.

  • Representación del contenido de las etiquetas del control.

El control MailLink reemplaza la propiedad TagKey para representar un elemento a en lugar del elemento span predeterminado representado por la clase WebControl. Debería reemplazar la propiedad TagKey si el elemento que desea representar es un miembro de la enumeración HtmlTextWriterTag. Muchas etiquetas de elementos HTML comunes se asignan a valores de la enumeración HtmlTextWriterTag. Por ejemplo, HtmlTextWriterTag.A corresponde a un elemento a y HtmlTextWriterTag.Table corresponde a un elemento table. Si el elemento que desea presentar no está representado por un miembro de la enumeración HtmlTextWriterTag, reemplace la propiedad TagName y devuelva la cadena que desea presentar como el elemento.

El control MailLink reemplaza los métodos de representación siguientes de la clase WebControl:

  • AddAttributesToRender para agregar un atributo href en la etiqueta de apertura que el control representa. Al reemplazar AddAttributesToRender, debería invocar siempre al método correspondiente de la clase base, como muestra el control MailLink. El método AddAttributesToRender de la clase WebControl implementa la lógica para agregar estilos y otros atributos en el elemento que el control Web representa, y lo llama el método RenderBeginTag de WebControl. Los atributos deben agregarse antes de que se represente la etiqueta de apertura. Esto significa que las llamadas a AddAttributesToRender o AddAttribute llegan antes que las llamadas a RenderBeginTag.

  • RenderContents para escribir el texto del hipervínculo (especificado por la propiedad Text) en las etiquetas del control. El control MailLink invoca al método WriteEncodedText de la instancia de HtmlTextWriter para codificar en HTML el texto introducido por el desarrollador de la página. En general, por motivos de seguridad, es preciso codificar en HTML el texto proporcionado por los usuarios.

El control MailLink muestra asimismo la persistencia del texto interno. MailLink permite al desarrollador de páginas especificar la propiedad Text en las etiquetas del control, tal como muestra el texto resaltado:

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

La persistencia interna contrasta con la persistencia predeterminada de la etiqueta de apertura del control, como en este ejemplo:

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

La persistencia predeterminada y la persistencia interna son idénticas en cuanto a funcionalidad. Para habilitar la persistencia interna, MailLink está marcado con el atributo ParseChildren(true, "Text"). El primer argumento del constructor ParseChildrenAttribute especifica que el analizador de páginas debería analizar el contenido de las etiquetas del control como propiedades en lugar de como controles secundarios. El segundo argumento proporciona el nombre de la propiedad interna predeterminada del control (en este ejemplo, Text). Cuando se llama al constructor ParseChildrenAttribute con estos dos parámetros, el contenido de las etiquetas del control debe corresponder a la propiedad interna predeterminada. El atributo PersistenceMode(PersistenceMode.InnerDefaultProperty) de la propiedad Text especifica que un diseñador visual debería serializar la propiedad como contenido interno en las etiquetas del control.

[WebControl] se marca con los atributos PersistChildren(false) y ParseChildren(true), que controlan la persistencia de la propiedad en tiempo de diseño y en tiempo de análisis. Estos atributos se heredan con el control y deben aplicarse sólo si se desea cambiar los valores heredados. El atributo PersistChildrenAttribute indica al diseñador si los controles secundarios de un control de servidor se conservan como controles internos anidados. El argumento false indica que el contenido interno corresponde a las propiedades, no a los controles secundarios. El atributo ParseChildrenAttribute se ha descrito en el párrafo anterior. Si la persistencia en tiempo de diseño y en tiempo de análisis de la clase [WebControl] es apropiada para su control, no es necesario que reemplace los atributos PersistChildrenAttribute y ParseChildrenAttribute heredados de [WebControl].

En el ejemplo siguiente se muestra una página .aspx que utiliza el control MailLink.

<%@ Page Language="VB" %>
<!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" >
  <title>MailLink test page</title>
</head>
<body>
  <form id="Form1" >
    <aspSample:MailLink id="maillink1" Font-Bold="true" 
      ForeColor="Green" Email="someone@example.com" >
      Mail Webmaster
    </aspSample:MailLink>
  </form>
</body>
</html>
<%@ page language="C#" %>
<!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" >
  <title>MailLink test page</title>
</head>
<body>
  <form id="Form1" >
    <aspSample:MailLink id="maillink1" Font-Bold="true" 
      ForeColor="Green" Email="someone@example.com" >
      Mail Webmaster
    </aspSample:MailLink>
  </form>
</body>
</html>

Generar y utilizar el ejemplo

Para obtener información sobre la generación del control y su uso en una página, vea Generar ejemplos de controles de servidor personalizados.

Vea también

Otros recursos

Desarrollar controles de servidor ASP.NET personalizados