ASP.NET WebParts Connections Tutorial
May 2004
Summary:
This article explains how you can use the WebPart Connections feature
to create more interesting WebParts that interact with each other.
Visits:
Contents
Download: Pending...
Introduction
Sample Scenario
Summary
Connections are a very powerful feature of WebParts that allows interchanging data
between two webparts, allowing creating more interesting non-monolitic WebParts.
Creating a connection is as easy as defining the interface that you want to connect
through. Think of it as the contract you are saying your WebPart supports and that
someone could at runtime request that interface and use it.
To have a connection one WebPart should act as a Provider and another WebPart should
act as a Consumer. The Provider exposes some data through a well defined interface,
that the consumer knows how to use.
Lets start creating the simplest Connection Sample possible, and as with all samples
we will start with the “Hello World” connection sample.
Using WebPart Connections
The steps we need to follow to establish a connection are:
- Define the interface that will connect both webparts
- Create a Provider WebPart
- a. Expose a Provider connection point to return this interface in a WebPart
- Create a Consumer WebPart
- a. Expose a Consumer connection point to request the interface
- Establish the connection
- Use the Interface in PreRender
The scenario that we will create is as simple as it gets. We will create a Provider
WebPart that will expose a single string property (called Message) that will be
consumed by another WebPart through a Connection. The consumer WebPart will only
display the Message in a Label.
To make it interactive we will expose a TextBox that will allow to change the Message
property in the Provider and this will update the Consumer as well.
Create a new Project
Create a new Web Application in Visual Web Developer or Visual Studio .NET.
Define the Interface for the connection
The first step is to define the interface through which the WebParts will communicate.
The ASP.NET WebPart Framework ships several interfaces to try to standardize a little
bit the creation of new webparts to try to enhance the intercommunication between
vendors, for example IField, IParameter, IRow, ITable, etc. You can also define your own interface if you want to.
In this sample since all the data we need to interchange is a string property we
will define our own interface.
Create the Code Directory
- Select the project node in the Solution Explorer.
- Right click it and select New Folder
- Type Code as the name of the folder
Note. the Code directory is new to ASP.NET 2.0 that allows developers to
place code inside this directory with the .cs or .vb extension and the asp.net build
infrastructure will compile the code on demand only when needed.
Add a new Interface in the Code directory.
- Select the Code folder
- Right click it and select the option Add New Item
- Select the option Class and type as the name IMessage
- Replace the content of the generated class with the following code.
C# Code:
public interface IMessage {
string Message { get;}
}
VB.NET Code:
Public Interface IMessage
ReadOnly Property Message() As String
End Interface
Create the Provider WebPart
After defining the interface, we need to create the WebPart that will expose it as a Provider.
To simplify the sample we will create a UserControl that we will use as a webpart, this is a really easy way to build webpart without having to understand the whole WebPart infrastructure.
Side
Note:
The WebPart framework only knows how to process WebParts, if you add a control that does not inherit from WebPart directly or indirectly (say UserControls,
WebControls, etc) then the WebParts Framework will "wrap" the control in a especial type of WebPart called GenericWebPart, this GenericWebPart class will try to look for specific WebPart attributes (ie those defined in IWebPart interface like Title, SubTitle, Description, etc) and extract the values to make it behave just as any other WebPart.
Create the User Control
- Select the Project node
- Right click it and select the option Add New Item
- Select the option Web User Control
- Type ProviderWebPart.ascx as the name for the UserControl
- Replace the content of the UserControl so that it looks as the following code
C# Code
<%@ Control Language="C#" ClassName="ProviderWebPart" %>
<%@ Implements Interface="IMessage" %>
<script runat="server">
[ConnectionProvider("Message")]
public IMessage GetMessage() {
return this;
}
public string Message {
get {
return _messageTextBox.Text;
}
}
</script>
<asp:TextBox Runat="server" ID="_messageTextBox" />
<asp:Button Runat="server" ID="_postBackButton" Text="Change the Text" />
VB.NET Code
<%@ Control Language="VB" ClassName="ProviderWebPart" %>
<%@ Implements Interface="IMessage" %>
<script runat='server'>
Public ReadOnly Property Message() As String _
Implements IMessage.Message
Get
Return _messageTextBox.Text
End Get
End Property
<ConnectionProvider("Message")> _
Public Function GetMessage() As IMessage
Return Me
End Function
</script>
<asp:TextBox Runat="server" ID="_messageTextBox" />
<asp:Button Runat="server" ID="_postBackButton" Text="Change the Text" />
This code defines a control that implements the interface IMessage that was previously defined.
It exposes a method called GetMessage() that returns an instance of such interface, since in this case the control itself implements the interface, it is safe to return
this. You could potentially create an instance of another object and returned it if needed.
This method has a Custom attribute that signals the ASP.NET WebPart framework that this method is to expose a Provider Connection Point so other webparts can connect to it.
Then it actually implements the Message property of the IMessage interface to return the value of the TextBox (_messageTextBox).
Finally I just added a button so we can change the text and click the button to see the Connections working.
Create the Consumer WebPart
Now we will create the consumer of such WebPart.
To simplify the sample we will create it using again a UserControl.
Create the User Control
- Select the Project node
- Right click it and select the option Add New Item
- Select the option Web User Control
- Type ConsumerWebPart.ascx as the name for the UserControl
- Replace the content of the UserControl so that it looks as the following code
C# Code
<%@ Control Language="C#" ClassName="ConsumerWebPart" %>
<script runat="server">
private IMessage _message;
[ConnectionConsumer("Message")]
void SetMessage(IMessage message) {
this._message = message;
}
protected override void OnPreRender(EventArgs e) {
if (_message != null)
_messageLabel.Text = _message.Message;
base.OnPreRender(e);
}
</script>
<asp:Label Runat="server" ID="_messageLabel" />
VB.NET Code
<%@ Control Language="VB" ClassName="ConsumerWebPart" %>
<script runat='server'>
Private _message As IMessage
<ConnectionConsumer("Message")> _
Sub SetMessage(ByVal message As IMessage)
Me._message = message
End Sub
Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
If (Not (_message) Is Nothing) Then
_messageLabel.Text = _message.Message
End If
MyBase.OnPreRender(e)
End Sub
</script>
<asp:Label Runat="server" ID="_messageLabel" />
This code defines a WebPart that acts as a consumer of the previous WebPart.
The way it works is it exposes a method that is marked with the attribute
ConnectionConsumer. This attribute signals ASP.NET WebPart Connections Framework that this method acts as a "receiver" of the IMessage interface.
At runtime the WebPart framework will request the Interface from the Provider and then it will call the SetMessage method passing the instance as the argument.
Note:One important thing to notice here is that you should not use the interface at this moment, it is only safe to use in the PreRender due to the fact that connections might depend on other connections and you can only be sure everything is set up correctly at the PreRender.
For this reason the only thing we do here is save a reference to such interface, so that we can use it in the PreRender to actually extract the values.
Creating the page
Now we will create the page where we actually use both webparts.
Create the Page
- Select the Project node
- Right click it and select the option Add New Item
- Select the option Web Form
- Type Sample.aspx as the name for the Page
- Replace the content of the Page so that it looks as the following code
C# Code
<%@ Page Language="C#" %>
<%@ Register TagPrefix="uc1" TagName="ProviderWebPart" Src="ProviderWebPart.ascx" %>
<%@ Register TagPrefix="uc2" TagName="ConsumerWebPart" Src="ConsumerWebPart.ascx" %>
<html>
<head>
<title>Sample Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:WebPartManager ID="WebPartManager1" Runat="server">
<StaticConnections>
<asp:Connection ID="SampleConnection" ConsumerID="ConsumerWebPart1" ProviderID="ProviderWebPart1" />
</StaticConnections>
</asp:WebPartManager>
<asp:WebPartZone ID="WebPartZone1" Runat="server">
<ZoneTemplate>
<uc1:ProviderWebPart Runat="server" ID="ProviderWebPart1" />
<uc2:ConsumerWebPart Runat="server" ID="ConsumerWebPart1" />
</ZoneTemplate>
</asp:WebPartZone>
</form>
</body>
</html>
VB.NET Code
<%@ Page Language="VB" %>
<%@ Register TagPrefix="uc1" TagName="ProviderWebPart" Src="ProviderWebPart.ascx" %>
<%@ Register TagPrefix="uc2" TagName="ConsumerWebPart" Src="ConsumerWebPart.ascx" %>
<html>
<head>
<title>Sample Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:WebPartManager ID="WebPartManager1" Runat="server">
<StaticConnections>
<asp:Connection ID="SampleConnection" ConsumerID="ConsumerWebPart1" ProviderID="ProviderWebPart1" />
</StaticConnections>
</asp:WebPartManager>
<asp:WebPartZone ID="WebPartZone1" Runat="server">
<ZoneTemplate>
<uc1:ProviderWebPart Runat="server" ID="ProviderWebPart1" />
<uc2:ConsumerWebPart Runat="server" ID="ConsumerWebPart1" />
</ZoneTemplate>
</asp:WebPartZone>
</form>
</body>
</html>
Running the Sample
To run the sample just browse to Sample.aspx.
Type some text in the TextBox and then click the Button.
Notice how the Consumer WebPart will automatically display the data from the Provider WebPart.
Connections are a very powerfull feature in WebParts that allow WebParts to interact data between them without having to know the details of the implementation.
In this tutorial we just scratched the surface of Connections, they are as complicated and rich as the whole WebPart Framework, they support several features, including multiple connections, Transformers (to adapt incompatible connections), one to many connections, secondary interfaces and many many more.