Пример подготовки веб-элемента управления для отрисовки

Обновлен: Ноябрь 2007

В этом примере показано создание элемента управления с именем MailLink, который отображает на веб-странице ссылку электронной почты путем представления элемента гиперссылки (<a>) в виде URI mailto:. Элемент управления демонстрирует типичные задачи, решаемые при выполнении отрисовки элемента управления, производного от класса WebControl.

Элемент управления MailLink предоставляет свойство Email для адреса электронной почты и свойство Text для отображаемого в гиперссылке текста. Разработчик веб-страницы может устанавливать эти свойства, как показано в выделенном тексте:

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

Разметка, созданная элементом управления, на стороне клиента будет выглядеть следующим образом:

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

Поведение URI mailto: может отличаться в разных обозревателях. В Internet Explorer, когда пользователь щелкает гиперссылку mailto:, обозреватель запускает почтовый клиент пользователя по умолчанию (если клиент электронной почты установлен и совместим с обозревателем). Код для элемента управления MailLink описывается ниже в подразделе «Рассмотрение кода».

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

Рассмотрение кода

Пример элемента управления MailLink иллюстрирует решение следующих задач:

  • Использование элементом управления нестандартных HTML-элементов.

  • Добавление атрибутов в открывающий тег элемента управления.

  • Добавление содержимого в теги элемента управления.

Элемент управления MailLink переопределяет свойство TagKey для отрисовки HTML-элемента <a> вместо HTML-элемента по умолчанию <span>, представляемого классом WebControl. Следует переопределить свойство TagKey, если требуемый HTML-элемент является членом перечисления HtmlTextWriterTag. Многие общие теги HTML-элементов отображаются на значения перечисления HtmlTextWriterTag. Например, HtmlTextWriterTag.A соответствует HTML-элементу <a>, а HtmlTextWriterTag.Table соответствует HTML-элементу <table>. Если требуемый HTML-элемент не представляется ни одним из членов перечисления HtmlTextWriterTag, переопределите свойство TagName и верните строку, представляющую его как HTML-элемент.

Элемент MailLink переопределяет следующие методы отрисовки класса WebControl:

  • AddAttributesToRender — для добавления атрибута href в открывающий тег, представляемый элементом управления. При переопределении AddAttributesToRender следует всегда вызвать соответствующий метод базового класса, как демонстрируется в коде элемента управления MailLink. Метод AddAttributesToRender класса WebControl реализует логику для добавления стилей и других атрибутов в HTML-элемент, представляемый веб-элементом управления, и вызывается из метода RenderBeginTag класса WebControl. Атрибуты должны быть добавлены перед интерпретацией открывающего тега. Это означает, что вызовы AddAttributesToRender или AddAttribute предшествуют вызовам RenderBeginTag.

  • RenderContents — для определения текста гиперссылки (заданном в свойстве Text) внутри тегов элемента управления. Элемент управления MailLink вызывает метод WriteEncodedText экземпляра HtmlTextWriter для преобразования в HTML-формат текста, введенного разработчиком веб-страницы. Вообще, в целях безопасности следует преобразовывать текст, предоставляемый пользователями, в HTML-формат.

Элемент управления MailLink также демонстрирует постоянство внутреннего текста. MailLink позволяет разработчику страницы указывать свойство Text внутри тегов элемента управления, как показано в выделенном тексте:

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

Внутреннее постоянство отличается от постоянства по умолчанию, используемого в открывающем теге элемента управления, как в следующем примере:

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

Постоянство по умолчанию и внутреннее постоянство функционально идентичны. Чтобы разрешить внутреннее постоянство, класс MailLink отмечается с помощью атрибута ParseChildren(true, "Text"). Первый аргумент конструктора ParseChildrenAttribute указывает, что синтаксический анализатор страниц должен интерпретировать содержимое тегов элемента управления как свойства, а не как дочерние элементы управления. Второй аргумент содержит имя внутреннего свойства по умолчанию элемента управления (в этом примере — Text). При вызове конструктора ParseChildrenAttribute с этими двумя параметрами содержимое тегов элемента управления должно соответствовать внутреннему свойству по умолчанию. Атрибут PersistenceMode(PersistenceMode.InnerDefaultProperty) свойства Text указывает, что визуальный конструктор должен сериализовать свойство как внутреннее содержимое тегов элемента управления.

WebControl отмечается с помощью атрибутов PersistChildren(false) и ParseChildren(true), которые управляют постоянством свойства во время проектирования и интерпретации страницы. Они наследуются элементом управления и должны применяться только в том случае, если требуется изменить наследуемые параметры. PersistChildrenAttribute сообщает конструктору, должны ли дочерние элементы серверного элемента управления сохраняться как вложенные внутренние элементы управления. Аргумент false указывает, что внутреннее содержимое соответствует свойствам, а не дочерним элементам управления. Атрибут ParseChildrenAttribute был описан в предыдущем абзаце. Если постоянство времени проектирования и времени интерпретации класса WebControl подходит для элемента управления, не требуется переопределять атрибуты PersistChildrenAttribute и ParseChildrenAttribute, унаследованные от класса WebControl.

В следующем примере показана веб-страница ASP.NET (файл с расширением ASPX), использующая элемент управления 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" 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"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://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>

Построение и использование примера

Дополнительные сведения о построении элемента управления и его использовании на странице см. в разделе Примеры связывания пользовательского серверного элемента управления.

См. также

Другие ресурсы

Разработка пользовательских серверных элементов управления ASP.NET