How to: Use Custom ASP.NET Server Controls in Visual Studio
You can make your custom server controls available in the Visual Studio Toolbox by defining the appropriate design-time attributes to be used by the visual designer. The following procedures create a simple control named MailLink, include it in the Toolbox, and use it to create an e-mail link in a Web page by rendering a hyperlink <a> element with a mailto: URL.
To create a custom control that contains design-time attributes
In Visual Studio, create a library project and define a custom class that derives from WebControl, as shown in the following example.
Note
The complete source code is listed in the Example section.
<Assembly: TagPrefix("Samples.AspNet", "Sample")> Namespace Samples.AspNet < _ ToolboxData("<{0}:MailLink ID='MailLinkID' Text='WebMaster' runat=""server""> </{0}:MailLink>")> _ Public Class MailLink Inherits WebControl ' Custom code goes here. End Class End Namespace
[assembly:TagPrefix("Samples.AspNet", "Sample")] namespace Samples.AspNet { [ ToolboxData("<{0}:MailLink ID='MailLinkID' Text='WebMaster' runat=\"server\"> </{0}:MailLink>") ] public class MailLink : WebControl { // Custom code goes here. } }
Add design-time attributes to provide custom metadata that will be used to display the control in the visual designer at design time. The following two design attributes are the only ones needed to make the MailLink control available in the Visual Studio Toolbox.
The TagPrefix attribute specifies the prefix in front of the control name MailLink. Together, the prefix and control name define the tag name for the custom control (in this case, <Sample:MailLink> </Sample:MailLink>).
<Assembly: TagPrefix("Samples.AspNet", "Sample")>
[assembly:TagPrefix("Samples.AspNet", "Sample")]
The ToolboxData attribute specifies the default tag generated for the MailLink control when it is dragged from the Toolbox into a page at design time.
<ToolboxData("<{0}:MailLink ID='MailLinkID' Text='Mail Webmaster' runat='server'"> </{0}:MailLink>")>
[ToolboxData("<{0}:MailLink ID='MailLinkID' Text='Mail Webmaster' runat=\"server\"> </{0}:MailLink>")]
Compile the MailLink control in a library and name it MaiLink.Dll.
To add the custom control to the Toolbox
On the View menu, click Toolbox.
In the Toolbox, right-click and select Choose Items.
In the Choose Toolbox Items dialog box, select the .NET Framework Components tab, and then click the Browse button to locate the MailLink.Dll you just built.
Select the check box for the MailLink control and click OK.
The custom MailLink control appears in the Toolbox.
To reference the MailLink control in a page
Create a new Web project. Then create a page named MailLink.aspx. This page will contain one of the following directives, depending on the language you selected for the project.
<%@ page language="VB" %>
<%@ page language="C#" %>
Add the following basic page structure to host the MailLink control.
<html xmlns="https://www.w3.org/1999/xhtml" > <head runat="server"> <title>Using the MailLink control</title> </head> <body> <h1>Using the MailLink Custom Server Control</h1> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
Switch to Design view and drag the MailLink control onto your page.
Visual Studio adds two items to the page: a Register directive for the MailLink control, and the tag name of the MailLink control to use in the page.
Run the page in a browser, and click the Mail Webmaster link.
A mail message opens, addressed to the address specified by the control's Email property.
Example
The MailLink control overrides the TagKey property to render an <a> element instead of the default <span> element rendered by the WebControl class.
Imports System
Imports System.ComponentModel
Imports System.Security
Imports System.Security.Permissions
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
<Assembly: TagPrefix("Samples.AspNet", "Sample")>
Namespace Samples.AspNet
<AspNetHostingPermission( _
SecurityAction.Demand, _
Level:=AspNetHostingPermissionLevel.Minimal), _
AspNetHostingPermission( _
SecurityAction.InheritanceDemand, _
Level:=AspNetHostingPermissionLevel.Minimal), _
ParseChildren(True, "Text"), _
DefaultProperty("Email"), _
ToolboxData("<{0}:MailLink ID='MailLinkID' Text='Mail Web Master' runat=""server""> </{0}:MailLink>")> _
Public Class MailLink
Inherits WebControl
<Browsable(True), Category("Appearance"), _
DefaultValue("webmaster@contoso.com"), _
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 = "webmaster@contoso.com"
Return s
End Get
Set(ByVal value As String)
ViewState("Email") = value
End Set
End Property
<Browsable(True), Category("Appearance"), _
DefaultValue("Web Master"), _
Description("The name to display."), _
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 'AddAttributesToRender
Protected Overrides Sub RenderContents(ByVal writer _
As HtmlTextWriter)
If [Text] = String.Empty Then
[Text] = Email
End If
writer.WriteEncodedText([Text])
End Sub 'RenderContents
End Class 'MailLink
End Namespace
using System;
using System.ComponentModel;
using System.Security;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
[assembly:TagPrefix("Samples.AspNet", "Sample")]
namespace Samples.AspNet
{
[
AspNetHostingPermission(SecurityAction.Demand,
Level = AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.InheritanceDemand,
Level = AspNetHostingPermissionLevel.Minimal),
ParseChildren(true, "Text"),
DefaultProperty("Email"),
ToolboxData("<{0}:MailLink ID='MailLinkID' Text='Mail Web Master' runat=\"server\"> </{0}:MailLink>")
]
public class MailLink : WebControl
{
[
Browsable(true),
Category("Appearance"),
DefaultValue("webmaster@contoso.com"),
Description("The e-mail address.")
]
public virtual string Email
{
get
{
string s = (string)ViewState["Email"];
return (s == null) ? "webmaster@contoso.com" : s;
}
set
{
ViewState["Email"] = value;
}
}
[
Browsable(true),
Category("Appearance"),
DefaultValue("Web Master"),
Description("The name to display."),
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);
}
}
}
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 in the following example.
<Sample:MailLink id="MaillinkID" Email="Webmaster@contoso.com"
runat="server">
Mail Support Team
</Sample:MailLink>
Inner persistence is in contrast to default persistence on the control's opening tag, as in the following example.
<Sample:MailLink Text="Mail Webmaster" runat="server" > </Sample:MailLink>
The preceding code is the default tag generated for the control when it is dragged from the Toolbox into a page.
Compiling the Code
In Visual Studio, create a library project and define a custom class that derives from WebControl, as shown in the procedure above. The complete source code is listed in the previous code section.
Security
Custom server controls extend the functionality of ASP.NET and must follow some precise security guidelines. In particular, you need to consider the following:
Run-time and design-time security.
Custom controls in strong-named assemblies.
Operating system security and access control lists (ACLs) on the server that hosts the custom server control.
Code access security to restrict the resources the control can access.
Managed assemblies in the global assembly cache.
See Also
Concepts
Design-Time Attributes for Components
Attributes and Design-Time Support
Securing Custom Server Controls