Establishing ASP.NET 2.0 WebPart Communication

I use a number of Web sites every day. Each Web site has a header, footer, some kind of navigation, and an area where I actually do my work. I am almost certain that each of these sites has "widgetized" or componentized its functional UI into smaller breakable pieces. For instance, the navigation is probably something a site reuses all over, so it is probably driven out of the same binaries, or code logic, on every part of the Web site. Clicking on the navigation widget would change what you see in the main content area.

So, if a site has two widgets, one for the menu/navigation and another for the content area, they obviously need to be able to communicate with each other. Also, clicking on one widget frequently updates more than one content area on a Web page. So, as a Web application developer, you need some kind of mechanism that allows these various widgets to communicate with each other.

The good news is the ASP.NET 2.0 WebPart framework comes with built-in support for such scenarios. You can have WebParts consume or provide data to other WebParts, and at design or run time, you can establish connections enabling various WebParts to communicate with them as necessary. These WebParts fall within two major categories:

  1. Providers, which make information available to other WebParts
  2. Consumers, which need and make use of that information

A number of consumers can consume information provided by a single provider. The information exchanged is defined by a communication contract, which is described in code as an interface. With these pieces in place, you can begin WebPart communication on your Web page. This article describes how.

To follow along, you need to have set up a WebPart framework and dropped a connections zone on the page already. Also, you need a link button, or some other mechanism on your Web page, that sets the WebPartManager in the "Connect" display mode. (If this sounds like Greek, I strongly recommend that you read my article on ASP.NET 2.0 WebPart framework basics first.)

ASP.NET 2.0 WebPart Connections Basics

The following four elements establish communication among WebParts:

  1. The communication contract: The first thing you need to do is decide what information the WebParts need to exchange, and then represent that in an interface you write. Because an interface you write serves as the communication contract, you have complete freedom to choose the structure of the information interchanged between WebParts. If two WebParts that need to communicate do not use the same interface to share information, they can still communicate using transformer objects, which are classes that inherit from the WebPartTransformer class.
  2. The Provider: A provider WebPart provides the information to be communicated by providing the consumer with an instance of a class that implements this interface. It provides this information in a method that is decorated with the ConnectionProvider attribute. Now, the class that implements the communication contract could be the provider itself, in which case it simply returns an instance of itself.
  3. The Consumer: The consumer WebPart simply needs to have a method that lets it get a hold of the provider, or a class that the provider intends the consumer to get. It creates a method that is decorated with the ConnectionConsumer attribute and accepts a parameter of the type held by the interface that describes the communication contract. Once the consumer has an instance that is of the type described by the communication contract, it can access various properties and methods to gain access to the information being communicated.
  4. Establish the communication: Once you have the communication contract written and the provider and consumer WebParts added to your Web page, you need to establish communication between the two or more WebParts. You can do this statically through the <StaticConnections> section within the WebPartManager, or at runtime through the browser using a ConnectionsZone.

With a grasp of the theory, you're ready to write two simple WebParts that communicate a string of text between them.

ASP.NET 2.0 WebPart Communication: A Code Example

To solidify your understanding of WebPart communication, take an exemplary problem. You will write two WebParts. One will show a textbox and an update button that provides information to the second WebPart, which simply consumes this information and displays it as text. By going through the four steps described above, you can write such an infrastructure.

The communication contract

The information you intend to communicate is a simple string. This means your communication contract can look like this:

public interface ITextContract
{
   string TheContent {get;set;}
}

Note that the ASP.NET 2.0 WebPart framework ships with some standard interfaces, such as IWebPartFIeld, IWebPartRow, IWebPartParameters, IWebPartTable, and so forth. Also, SharePoint 2007 libraries define a few such standard interfaces to help you establish a commonality and to get you off the ground easily by using one of the interfaces declared in the framework.

Writing the provider WebPart

The provider WebPart creates a method decorated by the ConnectionProvider attribute, which returns an instance of a class that implements the interface ITextContract you declared above.

Now, this class, which implements the interface, can be either the provider WebPart itself or some other class. Simply create a WebPart that implements the ITextContract interface to serve as the provider:

public class TheProvider: WebPart, ITextContract
{
    // Implementation goes here.
}

In this WebPart, you need a textbox to allow the user to input new string values and a button to cause a postback. You can do this very easily by using the following code:

private TextBox contentTextLabel;
private Button btnUpdate;

protected override void CreateChildControls()
{
   contentTextLabel      = new TextBox();
   contentTextLabel.Text = "Sample Text";
   btnUpdate             = new Button();
   btnUpdate.Text        = "Update Text";

   this.Controls.Add(contentTextLabel);
   this.Controls.Add(btnUpdate);
}

Also, implement the "TheContent" property that ITextContract requires as follows:

public string TheContent
{
   get { return contentTextLabel.Text; }
   set { contentTextLabel.Text = value; }
}

As you can see, you simply set and return the value contained in contentTextLabel, which is the value the user just entered.

Finally, add the requisite method decorated with the ConnectionProvider attribute, which returns an instance of ITextContract. This method will simply return an instance of the provider WebPart you are writing:

[ConnectionProvider("The Content")]
public ITextContract GetTextCommunicationPoint()
{
   return this as ITextContract;
}

Putting all these pieces together, the following is the full code for your provider WebPart:

public class TheProvider: WebPart, ITextContract
{
   private TextBox contentTextLabel;
   private Button btnUpdate;

   protected override void CreateChildControls()
   {
      contentTextLabel      = new TextBox();
      contentTextLabel.Text = "Sample Text";
      btnUpdate             = new Button();
      btnUpdate.Text        = "Update Text";

      this.Controls.Add(contentTextLabel);
      this.Controls.Add(btnUpdate);
   }

   public string TheContent
   {
      get { return contentTextLabel.Text; }
      set { contentTextLabel.Text = value; }
   }

   [ConnectionProvider("The Content")]
   public ITextContract GetTextCommunicationPoint()
   {
      return this as ITextContract;
   }
}

Writing the consumer WebPart

The Consumer WebPart is a rather simple WebPart that simply renders the text provided by the provider. To render information, it first needs an instance of ITextContact—in this case, an instance of the provider itself. You do this by creating a method decorated by the ConnectionConsumer attribute that accepts a single parameter of type ITextContract:

private ITextContract theProvider ;

[ConnectionConsumer("The Content")]
public void InitializeProvider(ITextContract provider)
{
   theProvider = provider ;
}

To render some text, you can simply add an instance of a Label control to the controls collection of the WebPart:

private Label lblText;

protected override void CreateChildControls()
{
   lblText = new Label();
   this.Controls.Add(lblText);
}

Now, any value set to lblText.Text will render at runtime. What is left is hooking up the ITextContract instance in the theProvider variable and lblText.Text property. You easily can achieve this in the OnPreRender method:

protected override void OnPreRender(EventArgs e)
{
   base.OnPreRender(e);

   if (theProvider != null)
   {
      lblText.Text = theProvider.TheContent ;
   }
}

Putting all these pieces together, the following is the complete code for your consumer WebPart:

public class TheConsumer : WebPart
{
   private ITextContract theProvider ;
   private Label lblText;

   protected override void CreateChildControls()
   {
      lblText = new Label();
      this.Controls.Add(lblText);
   }

   [ConnectionConsumer("The Content")]
   public void InitializeProvider(ITextContract provider)
   {
      theProvider = provider ;
   }

   protected override void OnPreRender(EventArgs e)
   {
      base.OnPreRender(e);

      if (theProvider != null)
      {
         lblText.Text = theProvider.TheContent ;
      }
   }
}

With the provider and consumer written up, you are ready to begin establishing communication between these WebParts.

Establishing ASP.NET 2.0 WebPart Communication

Establish the communication

You establish communication by specifying its details in one of three ways:

  1. Declaratively using the <StaticConnections> element in the WebPartManager
  2. Programmatically using the ConnectionPoint, ConsumerConnectionPoint, and ProviderConnectionPoint classes
  3. Pointing and clicking through a browser UI using the Connections Zone

This article demonstrates using Option #3 to set up communication.

Assuming that you have already set up a WebPart framework (my previous article demonstrated how), add a connections zone to your Web page:

<asp:ConnectionsZone ID="ConnectionsZone1" runat="server"/>

Also, add the Consumer and Provider WebParts to the DeclarativeCatalogPart:

<asp:DeclarativeCatalogPart ID="DeclarativeCatalogPart1"
                            runat="server">
   <WebPartsTemplate>
      <cc4:TheConsumer ID="TheConsumer"
         runat="server"
         Title="Communication Consumer"
         Description="This consumes the text."/>
      <cc4:TheProvider ID="TheProvider"
         runat="server" Title="Communication Provider"
         Description="This provides the text." />
   </WebPartsTemplate>
</asp:DeclarativeCatalogPart>

Now, run the Web application, and add an instance of the Consumer and an instance of the Provider to WebPartZone(s) on an aspx page. See the WebParts with the WebPartManager in Catalog DisplayMode below:

[Sahil1.jpg]

Now, set the page in "Connect" DisplayMode. You should see "Connect" verbs appear next to the WebPart title bars as shown below:

[Sahil2.jpg]

Click on "Connect" for either WebPart. The processes for the consumer and the provider are essentially reversed, so just click on the provider's connect for this example, and experiment with the connect verb of the consumer at your convenience.

When you click on "Connect" for the provider, you should see a UI similar to the following appear in the ConnectionsZone:

[Sahil3.jpg]

Click on "Create a connection to a consumer" and choose the Communication consumer as shown below:

[Sahil4.jpg]

Next, you see the connections zone UI change to the following:

[Sahil5.jpg]

Also, notice that the Communication Consumer now shows the text value held by the Communication Provider:

[Sahil6.jpg]

Put the page in "Browse" display mode, change the "Sample Text" to "Extraordinary Text," and click "Update Text." You should see the two WebParts communicating with each other as shown below:

[Sahil7.jpg]

Congratulations. You've just established communication between two WebParts.

Further Steps

WebPart communication is an incredibly powerful tool that allows you to build complex and functional Web sites using various widgets. Also, you could wrap the WebPartZone inside an Atlas UpdatePanel and remove all postbacks involved in such communication. With a little style sheet magic, you could show a WebPartZone that holds the consumer as a popup. For example, you could create a WebPart that receives an English word, queries a dictionary over a Web service, and displays its meaning in a popup. Then, all WebParts that display content on a Web page could respond to double clicks and show a pop-up dictionary to the end user. Not only that, you could show tracking information for packages, live maps for addresses, and any other information that may make sense to communicate between WebParts.

The best part is that, once you have established a WebPart framework and a number of functional WebParts, you could set up such Web sites through a browser UI at runtime—just like SharePoint 2007. Thus, it isn't surprising that SharePoint 2007 can make good use of the ASP.NET 2.0 WebPart framework connections.

About the Author

Sahil Malik (www.winsmarts.com) has worked for a number of top-notch clients in Microsoft technologies ranging from DOS to .NET. He is the author of Pro ADO.NET 2.0 and co-author of Pro ADO.NET with VB.NET 1.1. Sahil is currently also working on a multimedia series on ADO.NET 2.0 for Keystone Learning. For his community involvement, contributions, and speaking, he has also been awarded the Microsoft MVP award.



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • By providing complete access control with granular permissions, deployment flexibility, mapped drive support, and ability to transfer large files, Egnyte provides a more robust, secure and an affordable file sharing solution for the business than Box

  • Live Event Date: April 29, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Leveraging Flash storage to accelerate an Oracle Real Application Clusters (RAC) environment is one of today's hottest technology topics. Oracle databases require guaranteed levels of storage performance and high availability of data. Until recently, Oracle RAC could only use Flash storage for SmartFlash Cache, which addresses some performance improvements, but limits the benefits that can be gained from a shared Flash infrastructure. Enter …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds