Web コントロールのレンダリングの例
更新 : 2007 年 11 月
この例では、Web ページでハイパーリンク (<a>) 要素と mailto: URI をレンダリングすることによって電子メールのリンクを作成する MailLink というコントロールを作成する方法を示します。このコントロールは、WebControl クラスから派生するコントロールをレンダリングする際に一般的に実行するタスクを示します。
MailLink コントロールは、電子メール アドレスを表す Email プロパティおよびハイパーリンクに表示するテキストを表す Text を公開します。ページの開発者は、強調表示されたテキストで示されているように 2 つのプロパティを設定できます。
<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>
mailto: URI の動作は、ブラウザによって異なる場合があります。Internet Explorer でユーザーが mailto: ハイパーリンクをクリックすると、ユーザーの既定の電子メール クライアントが起動されます (電子メール クライアントがインストールされ、ブラウザと互換性がある場合)。MailLink コントロールのコードについては、この後の「コードの説明」で説明します。
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 コントロールの例によって、次のようなタスクを示します。
コントロールの既定以外の要素をレンダリングする。
コントロールの開始タグの属性をレンダリングする。
コントロールのタグの内容をレンダリングする。
MailLink コントロールは、TagKey プロパティをオーバーライドし、WebControl クラスがレンダリングする既定の <span> 要素の代わりに <a> 要素をレンダリングします。レンダリングする要素が HtmlTextWriterTag 列挙のメンバである場合は、TagKey プロパティをオーバーライドする必要があります。多くの一般的な HTML 要素のタグが HtmlTextWriterTag 列挙の値にマップされています。たとえば、HtmlTextWriterTag.A は <a> 要素に対応し、HtmlTextWriterTag.Table は <table> 要素に対応します。レンダリングする要素を HtmlTextWriterTag 列挙のメンバによって表すことができない場合、TagName プロパティをオーバーライドし、要素としてレンダリングする文字列を返します。
MailLink コントロールは、WebControl クラスの次のレンダリング メソッドをオーバーライドします。
コントロールによってレンダリングされる開始タグの href 属性を追加する AddAttributesToRender メソッド。AddAttributesToRender をオーバーライドするときは、MailLink コントロールに示されているように、必ず基本クラスの対応するメソッドを呼び出す必要があります。WebControl クラスの AddAttributesToRender メソッドは、Web コントロールがレンダリングする要素にスタイルおよびその他の属性を追加するためのロジックを実装し、WebControl の RenderBeginTag メソッドによって呼び出されます。属性は、開始タグをレンダリングする前に追加する必要があります。つまり、RenderBeginTag への呼び出しの前に、AddAttributesToRender または AddAttribute への呼び出しを行います。
コントロールのタグの内部でハイパーリンクのテキストを記述する RenderContents メソッド (Text プロパティで指定)。MailLink コントロールは HtmlTextWriter インスタンスの WriteEncodedText メソッドを呼び出して、ページの開発者が入力した定義を 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 コンストラクタの最初の引数は、ページ パーサーがコントロールのタグの内容を子コントロールとしてではなく、プロパティとして解析する必要があることを指定します。2 番目の引数は、コントロールの内部の既定のプロパティの名前を提供します (この例では Text)。この 2 つのパラメータを使用して ParseChildrenAttribute コンストラクタを呼び出す場合、コントロールのタグの内容は内部の既定のプロパティに対応する必要があります。Text プロパティの PersistenceMode(PersistenceMode.InnerDefaultProperty) 属性は、ビジュアル デザイナがプロパティをコントロールのタグの内部コンテンツとしてシリアル化する必要があることを指定します。
WebControl は、デザイン時と解析時の永続性を指定する PersistChildren(false) 属性と ParseChildren(true) 属性によってマークされます。これらはコントロールによって継承されるため、継承された設定を変更する場合のみ適用する必要があります。PersistChildrenAttribute は、サーバー コントロールの子コントロールが入れ子になった内部コントロールとして永続化する必要があるかどうかをデザイナに指定します。引数 false は、内部コンテンツが子コントロールではなくプロパティに対応することを示します。ParseChildrenAttribute については、前に説明しています。WebControl クラスのデザイン時と解析時の永続性がコントロールに適している場合、WebControl から継承される PersistChildrenAttribute 属性と ParseChildrenAttribute 属性をオーバーライドする必要はありません。
MailLink コントロールのテスト ページ
MailLink コントロールを使用する ASP.NET Web ページ (.aspx ファイル) の例を次に示します。
<%@ 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>
例のビルドと使用
コントロールをビルドしてページ内で使用する方法については、「カスタム サーバー コントロールの例のビルド」を参照してください。