Contents
Download: Pending ... IntroductionSample Scenariosummary
Introduction
Connections are a very powerful feature of WebParts that allows interchanging data between two webparts, allowing creating more interesting non-monolitic WebParts. A connection in WebParts is essentially the ability to expose an interface to a WebPart (Provider) that another WebPart (Consumer) can connect to and use it. This is an interesting feature that allows the creation of atomic units that are completely decoupled from each other. This allows end users to connect WebParts from different vendors to interact their web site even when the vendors were never aware of them . ASP.NET WebPart connections give a lot of flexibility allowing WebPart developers to expose any arbitrary interfaces that might include events, methods, properties or anything that interfaces allow. This allows building interesting connections that can allow consumers notify providers using methods or events. However , with this flexibility comes a Problem, Each Vendor Might Start Defining Their Own Interfaces Which Will make potentially imposible to end users inter-connect WebParts SeemLY. ASP.NET UNDERSTAND The Problem and to MitiGate It, IT Has Two Features:
It defines a pre-defined set of "standard" interfaces that different vendors could try to stick to, so their webparts are more "connectable". Interfaces like IField, IParameters, IRow, etc try to provide common patterns of data interchange. Transformers. This feature allows to build Special "Bridges" That Allows to connect Webparts That by definition is what we will be covering in this article.
Sample Scenario
The scenario that we will create is the simplest transformer possible.Lets assume we downloaded a DLL from a WebSite that "vendor A" created. This webpart exposes a connection with an interface IFoo (FooProvider WebPart). We also downloaded from another site a WebPart that knows how to consume an interface called IBar (BarConsumer WebPart). The problem that we have is that we would want to connect them to share data, but they are incompatible since they expose / consume different interfaces, so the ASP.NET WebPart Framework will not allow us to connect them. So our job is to create the "bridge" that will tell the WebPart framework that they are "connectable", and that we know how to translate between one and the other.Create a new Project
Create a New Web Application In Visual Web Developer or Visual Studio .NET 2005.
Create the WebParts
Even though this sample is not meant to show how to do the WebParts and the connections, we will show the code so you see how simple it is. Just keep in mind that you do not need the source code of WebParts, or the interfaces to BE ABLE TO Build a Transformer That Converts Between Two Different WebParts.
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. In the Beta2 it Might be renamed to be caled application_code.
Add A New Barconsumer File to The Directory.
SELECT The CODE FOLDER RIGHT CLICK IT AND SELECT The OPTION AND TYEM Sing The name barconsumer replace the content of the generated class with the folding code.c # code:
Namespace
Carlosag.samples {
Using
SYSTEM
Using
System.Web.ui
Using
System.Web.ui.WebControls.webparts
;
///
Public Interface
IBAR {
int
Integerdata {
Get;
}
///
Public class
Barconsumer: WebPart {
Private
Ibar _bar
;
///
[ConnectionConsumer "
"Ibar consumer"
)]]
Public void
SetProvider (IBAR BAR) {
THIS
._bar
=
Bar
;
}
///
Protected Override Void
RenderContents (HTMLTextWriter Writer) {
IF
(_bar!
= NULL
) {Writer.write
Integer Data: "
_BAR.INTEGERDATA.TOSTOSTRING ())
;
}
Else
{Writer.write
"Ibar is null"
)
;
}}}}
VB.Net Code:
Imports
SYSTEM
Imports
System.Web.ui
Imports
System.Web.ui.WebControls.webparts
Namespace
Carlosag.samples
'
Public Interface
Ibar
Readonly Property
Integerdata ()
AS integer end interface
'
Public classbarconsumer
Inherits
WebPart
Private
_bar
AS
Ibar
'
"Ibar consumer" > _ Public SUB SetProvider BYVAL Bar AS IBAR) ME ._bar = Bar End Sub ' Protected Overrides Sub RenderContents BYVAL Writer AS HtmlTextWriter) IF ( NOT (_bar) IS Nothing) THEN Writer.write Integer Data: " _BAR.INTEGERDATA.TOSTRING)) Else Writer.write "Ibar is null" ) End if End Sub End Classend Namespace As you can see creating a consumer is extremely easy, just expose a public method that has no return value, that receives one object and that is tagged with the ConnectionConsumer attribute. Once you do that, just make sure to save a reference of the object Passed and use it lated, say at prerender, or render methods, to ensure everything is connected Correctly. Create the providerwebpart Create The Fooprovider Class SELECT The CODE Folder Node Right Click IT and SELECT The OPTION TYPE FOOPROVIDER As The Name and Replace The Content As Follows C # code Namespace Carlosag.samples { Using SYSTEM Using System.Web.ui.WebControls Using System.Web.ui.WebControls.webparts ; /// Public Interface IFOO { String StringData { Get; } /// Fooprovider: WebPart, IFOO { Private Textbox _DataTextBox ; /// [Personalizable (PersonalizationScope.User)] Public String Data { get { Return Textbox.text ; } set {TextBox.text = Value; } /// protected Textbox textbox { get {ENSURECHILDCONTROLS () Return _DataTextBox ; } /// public Fooprovider () {} /// Protected Override Void CreateChildControls () {label _label = New Label () ; _Label.Text = "Enter a number:" ; _Label.Font.Bold = True; THIS .Controls.add (_Label) ; _DataTextBox = New Textbox () ; _DataTextBox.Autopostback = True; _DATAXTBOX.TEXTCHANGED = New EventHandler (_DataTBox_TextChanged) This .Controls.add (_DataTextbox) ; } /// Private void _DATATBOX_TEXTCHANGED ( Object Sender, Eventargs E) {data = Textbox.text ; } // ***************************************************** / / Here starts the connection related code // ***************************************** ****** /// "Ifoo provider" )]] public Ifoo getProvider () { Return this; } /// String Ifoo.stringdata { get { Return this .DATA ; }}}} VB.NET CODE Imports SYSTEM Imports System.Web.ui.WebControls Imports System.Web.ui.WebControls.webparts Namespace Carlosag.samples ' Public Interface IFoo Readonly Property StringData () AS String End Interface ' Public class Fooprovider Inherits WebPart IMPLEMENTS IFoo Private _DataTextBox AS Textbox ' Public Sub New () Mybase . New () End Sub ' Public Property Data () AS String Get Return Textbox.text End Get Set ( BYVAL Value As string TextBox.Text = Value End Set End Property ' Protected readonly propertyTextBox () AS Textbox Get EnsureChildControls () Return _DataTextBox End Get End Property ' Readonly Property Ifoo_stringdata () As string _ IMPLEMENTS Ifoo.stringData Get return me .DATA End Get End Property ' Protected Overrides Sub CreateChildControls () DIM _Label AS Label = New Label _Label.Text = "Enter a number:" _Label.Font.Bold = True ME .Controls.add (_Label) _DataTextBox = New Textbox _DataTextBox.Autopostback = True AddHandler _DataTBox.TextChanged, Addressof ME ._datatextbox_textchanged ME .Controls.add (_DataTextbox) End Sub ' Private sub _DATATBOX_TEXTCHANGED ( BYVAL Sender As Object , _ BYVAL e AS Eventargs) Data = Textbox.text End Sub '***************************************************** ARE STARTS THE CONNECTION RELATED CODE '******************************************************************************** *** ' "Ifoo provider" > _ Public Function GetProvider () AS IFoo Return Me End Function End Classend Namespace Creating the page Now We Will Create The page where we actload. 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 codeCode <% @ Page language = "c #"%> <% @ Register tagprefix = "sample" namespace = "carlosag.samples"%> < HTML > < HEAD Runat = "Server"> < Title > Transformer Sample < / Title > < / HEAD > < Body > < FORM id = "Form1" Runat = "Server"> < ASP: WebPartManager Id = "WebPartManager1" Runat = "Server" /> < ASP: WebPartPageMenu Id = "WebPartPageMenu1" Runat = "Server" /> < HR /> < ASP: WebPartZone Id = "WebPartzone1" Runat = "Server" ParttitleStyle-BackColor = "# 99ccff"> < ZoneTemplate > < Sample: fooprovider Title = "Foo provider" Runat = "Server" Id = "Fooprovider1" Data = "23" /> < Sample: Barconsumer Title = "Bar Consumer" Runat = "Server" Id = "Barconsumer1" /> < / ZoneTemplate > < Partstyle Bordercolor = "Slet" Borderstyle = "Solid" Borderwidth = "4px" /> < / ASP: WebPartZone > < Br /> < ASP: Connectionszone Id = "Connectionszone1" Runat = "Server" Headerstyle-BackColor = "# 99ccff" /> < / FORM > Body > < / HTML > If you try running the page now, you should be able to see both webparts working, you can use the WebPartPageMenu to switch to connect mode, and you will notice that no connection can be established, since as we said they are incompatible. Creating the transformer Now We Will Create The Actual Transformer Class That Will Allow US to Connect Both WebParts. Create The Footobartransformer Class SELECT The CODE NODE Right Click IT and SELECT The OPTION TYPE FOOTOBARTRANSFORMER As The Name for The Class Replace The Content So That Looks as The Following Code C # code Namespace Carlosag.samples { Using SYSTEM Using System.Web.ui.WebControls.webparts ; [Transformer " Typeof (Ifoo), Typeof (Ibar)]] Public class Footobartransformer: transformer, ibar {ifoo _foo ; /// Public Override Object TRANSFORM Object providerdata) {_foo = (IFoo) providerdata Return THIS; } /// int IBAR.INTEGERDATA { get { IF (_foo.stringdata! = NULL ) { Try { Return Int .Parse (_foo.stringdata) ; } Catch {}} Return - 1 ; }}}} VB.NET CODE Imports SYSTEM Imports System.Web.ui.WebControls.webparts Namespace Carlosag.samples Gettype (Ifoo), Gettype (Ibar)> _ _ Public class Footobartransformer Inherits TRANSFORMER IMPLEMENTS Ibar Private _foo AS IFoo ' Readonly Propertyibar_integerData () As integer _ IMPLEMENTS IBAR.INTEGERDATA Get IF ( NOT (_foo.stringdata) IS Nothing) THEN RETURN CINT (_foo.stringdata) Catch EX AS SYSTEM. Exception END TRY END IF RETURN - 1 End Get End Property ' Public overrides function TRANSFORM BYVAL ProviderData As Object ) As Object _foo = CTYPE (ProviderData, IFOO) Return Me End Function End Classend Namespace If you try running the page again, you will still see you are not able to connect them. The reason for this is that in order for transformers to work you have to "publish" them in the web.config or machine.config. Modifying the web.config Open the Web.config and add the webparts section................ Web.config < XML Version = "1.0" ? > < CONFIGURATION XMLNS = "http://schemas.microsoft.com/.netconfiguration/v2.0"> < System.Web > < Authentication Mode = "Windows" /> < WebParts > < TRANSFORMERS > < Add Name = "Foo to bar transformer" Type = "Carlosag.samples.footobartransformer" /> < / TRANSFORMERS > < / WebParts > < / System.Web > < / CONFIGURATION > Running the Sample TO Run The Sample Just Browse to Sample.aspx. Select The Connect WebParts Option In The Drop Down Menu and SELECT The CHANGE Button Click the Connect Verb from the Popup Menu that will appear in the Title of the Provider WebPart.At this point the WebPart framework will realize that this WebPart can only be used as a provider and will enable only a link to connect to a consumer. Click The Link "CREATE A Connection To a Consumer". The WebPart Framework Will Look for All Compatible Consumer Connections and Will Look for Possible Transformers As Well. IT Will REALIZE That The Footobartransformer Is Available and So It Will Display As a Possible Connection The Foo -> Bar. Select The Bar Consumer from The Drop Down, and Click Connect. At this Point The WebParts Are Connected, So Type Some Numbers in The Text Box and Press Tab, or Move The Focus Out of The Text Box So The AutoPostback Works And Will Update The Second Webpart. Summary Connections are a very powerfull feature in WebParts. Transformers give the ability to connect webparts that otherwise would be incompatible. In this tutorial we just scratched the surface of Transformers, there are other methods that you could use to create a User interface to prompt for additional Values or Parameters for your transformer as well as something..............