My blog has moved!

My blog has moved to http://www.lamber.info. Click on the redirect button below to be redirected to the blog post.

Please update your bookmarks and use the new url for getting new updates.

Pages

Friday, July 30, 2010

How do I pass/exchange data between two Visual Web Parts?

Hi all,

in this post of the post series Visual WebParts, we are looking how to make two Visual WebParts exchange data on the same page. In this way you are able to solve some more complex scenarios like a master-child relation ship between two WebParts. This post tells you how to use this built-in functionality by using WebPart connections. WebPart connections are interfaces that define the communication between a provider of content and a consumer of content. The content provider WebPart exposes data to an interface you have to specify. This interface can then be used to consume this exposed data in the content consumer.

Walkthrough

In this post we are going to exchange a single integer value from the provider WebPart to the consumer. We are only showing how to set up the connection. However, this information is enough to create WebPart connections that are more complicated. When you are developing a WebPart connection, you have to follow these basic steps:

  • Step 1: create the interface for the data you want to expose
  • Step 2: create your provider WebPart with the definition of the interface you previously created
  • Step 3: create your consumer WebPart and use the interface you previously created to consume the data
  • Step 4: add the WebParts to your page and connect them together with the WebPart menu of the provider WebPart

Note: as I created this tutorial, I noticed that the WebPart connections are not working in a Wiki page of SharePoint 2010. Therefore, use a WebPart page with WebPart zones to verify the results.

Step 1: create the interface for the data you want to expose

First of all, we need to create a new Visual WebPart project in Visual Studio 2010. If you still don’t know how to do this, you can see how to do this in my Visual WebPart post series. After, we create a simple C# interface that will be used to define our simple data connection.

  • create a new Visual WebPart project in Visual Studio 2010
  • add a new Interface and call it for the sake of this example IProvideMyAge
  • open the file IProvideMyAge.cs and put the code that follows
public interface IProvideMyAge 
{
int Age { get; }
}

Note: this simple interface provides only one simple data definition. You can put as many values as you want and also consume complex or custom types. The only requirement is that these types are marked as serializable

Step 2: create your provider WebPart

Now that we created our interface, we have to tell our Visual WebPart to use this interface and provide a WebPart connection point. For the sake of the example we will only define this connection point and put a hardcoded value for the data that later will be consumed.

  • delete the WebPart that was automatically generated in the project. It’s name is probably VisualWebPart1
  • Add a new Visual WebPart and call it MyProvider
  • Open the file MyProvider.cs and verify the code that follows. You have to do some little changes. You can verify the changes in the next code snippet:
    • Add the interface IProvideMyAge to the WebPart on line 1
    • Create a method that specifies the name of the connection provider (line 12-16) and returns the current instance of the WebPart
    • implement the interface property provided by the IProvdeMyAge interface on line 18-23
public class MyProvider : WebPart, IProvideMyAge2) 
{
// Visual Studio might automatically update this path when you change the Visual Web Part project item.
private const string _ascxPath = @"~/_CONTROLTEMPLATES/WebPartConnections/MyProvider/MyProviderUserControl.ascx";

protected override void CreateChildControls()
{
Control control = Page.LoadControl(_ascxPath);
Controls.Add(control);
}

[ConnectionProvider("TheAgeInterface")]
IProvideMyAge WhatIsMyAge()
{
return this;
}

int IProvideMyAge.Age
{
get
{
return 27;
}
}
}

Step 3: create your consumer WebPart

Before, we created the data interface and the provider Webpart. Now, it’s time to create our consumer WebPart. We are working with Visual WebParts. Therefore, we have to work on two different classes. The user control that will present the data of the WebPart class that we are going to create and the WebPart class itself that will contain our consumption point. The steps to follow are:

  • create the consumer and define the consumption point
  • tell the user control loaded in your WebPart who you are by passing your reference
  • create a property that will hold your WebPart class in the user control

  • add a label to the user control
  • fill in the “OnPrerender” method your label with the value collected from the WebPart

Now, we are going to create the Visual WebPart and define our consumption point:

  • Add a new Visual WebPart and call it MyConsumer
  • Open MyConsumer.cs and the code that follows
public class MyConsumer : WebPart
{
// Visual Studio might automatically update this path when you change the Visual Web Part project item.
private const string _ascxPath = @"~/_CONTROLTEMPLATES/WebPartConnections/MyConsumer/MyConsumerUserControl.ascx";

protected override void CreateChildControls()#
{
MyConsumerUserControl control = Page.LoadControl(_ascxPath) as MyConsumerUserControl;
control.WebPart = this;
Controls.Add(control);
}

public int Age { get; set; }
[ConnectionConsumer("TheAgeInterface")]
public void SetAge(IProvideMyAge age)
{
if (age != null)
{
this.Age = age.Age;
}
}
}

Notice that with lines 8-9 we are passing to a property of our user control the current WebPart reference (we will create the property in the user control in the next steps). We defined a property on line 13 to expose our data to our user control afterwards. Line 14-21 defines the consumption method of our consumer WebPart.

Note: the name of the connection must be the same as the name defined in our provider.

Now, let us finish the work by making the last changes on our user control.

  • Open MyConsumerUserControl.ascx and put there a label
  • Open MyConsumerUserControl.ascx.cs and define the code as follows
public partial class MyConsumerUserControl : UserControl
{
public MyConsumer WebPart { get; set; }

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
this.Label1.Text = this.WebPart.Age.ToString();
}
}

We defined in line 3 the property we populated before in our WebPart. This WebPart reference is then used in the OnPreRender method to populate the value in our label control we added to our user control. Now, we are ready to publish our project and test our simple connection.

Step 4: add the WebParts to your page and connect them

We finish up our example by publishing the WebParts and by creating a WebPart connection manually.

  • publish the WebPart project to SharePoint 2010
  • add both deployed WebParts to a page with WebPart zones
  • open the WebPart menu of your provider Webpart and you will notice a menu item called Connection
  • follow this menu and create the connection with the desired consumer WebPart (in our example there should be only one listed WebPart)

After the connection, you should see the magic and the value 27 in the label of your consumer WebPart.

Summary

WebPart connections give you the possibility to pass values from a provider WebPart to a consumer WebPart. In this post you saw the basic steps you need to follow to accomplish this task. The WebPart framework does the rest for you. If you want to get more information about this topic, just follow this link.

 

Hope this helps,

Patrick

Wednesday, July 21, 2010

I can’t attach for debugging Visual Studio 2010 to my SharePoint 2007 w3wp process…

Hi,

if you want to debug custom code with SharePoint 2007, you have to attach your project in Visual Studio to the w3wp process of your SharePoint site. It is also important to ensure that the code in your project is the same as the version deployed on your SharePoint solution. Otherwise, you will not be able to set a breakpoint and stop on your desired code location. Until now, nothing new.

Today, however, my colleagues came across a strange issue. They wanted to attach their project to a SharePoint process for debugging. Unfortunately, after several trials, they where still unsuccessful. After a while, we sit down and tried to remember the environmental changes we made in the last weeks and debugging session to find a potential issue. We changed to a new testing environment. This is what exactly changed:

  • server hardware
  • server name
  • new SharePoint installation
  • Visual Studio 2010 and .NET Framework 4.0 except Visual Studio 2008

We started to verify again the “Attach to process” dialog of Visual Studio 2010 to see if we can find a solution. Fortunately, the solution was really near and we solved it in few seconds. At the end, we needed to specify the “Code Types” to attach in the “Attach to process” dialog. It seems that you have to specify it when attaching to a process by following these steps:

image

Hope this helps,

patrick

Friday, July 16, 2010

How do I access private methods, properties and member variable not controlled by me in C#?

I’m back from my marriage and honey moon. So now I’m again having time to do some blogging activities. ;)

Currently, I’m writing a migration procedure from one custom framework (call it framework A) to the other (call it framework B). During the development of the migration procedure I needed the access on the value of a member variable in framework A. Unfortunately, this member variable was private and there was no way to retrieve in another way. Neither, I had the access to the source code of framework A to change the member variable to public. “Damn… how do I get this value?… I need it only once for the migration…”. After a while a simple but effective idea came into my head: Use reflection! In this post I’m going to show a small example on how accessing the private values of an object in C#.

Note: please use reflection carefully. It is a really powerful functionality of C# but is a quite expensive task in execution time.

Walkthrough

In this posing we are creating a simple console application with a class called PrivateClass. The code of this class is shown in the next code snippet.

namespace ReflectionTest
{
public class PrivateClass
{
public PrivateClass()
{
this._privateText = "You can't change me";
this.PrivateNumber = 11;
}

private String _privateText;
private int PrivateNumber { get; set; }

public override string ToString()
{
return String.Format("PrivateNumber: {0}; PrivateText: {1}", this.PrivateNumber, this._privateText);
}
}
}

This example covers the access of a private member variable (line 11) and a private property (line 12). With this class, we are going to show following small demos:

  • Demo 1: How do I access the content of the private member variable with reflection?
  • Demo 2: How do I modify the content of the private member variable with reflection?
  • Demo 3: How do I access the content of the private property with reflection?
  • Demo 4: How do I modify the content of the private property with reflection? 

Demo 1: How do I access the content of the private member variable with reflection?

An example of how to retrieve a value from a private member variable can be seen in the next code snippet:

static void Main(string[] args)
{
PrivateClass myPrivateClass = new PrivateClass();

// input from ToString() at the beginning to see the content
Console.WriteLine(myPrivateClass);

FieldInfo fi = typeof(PrivateClass).GetField("_privateText", BindingFlags.NonPublic | BindingFlags.Instance);
String valueFromPrivateField = fi.GetValue(myPrivateClass).ToString();
Console.WriteLine("And this was read with reflection: {0}", valueFromPrivateField);
}

In this example, we are first instantiating the class to initialize all desired values and output them in the console output with the overwritten toString method on line 5. The next step is to get the FieldInfo of the desired field in our class. This class contains all necessary information about our field for further processing.

Line 7 searches the field called privateText. With the second parameter we are guaranteeing that we are also getting back a result with a private field. At the end, we can use the “FieldInfo” to retrieve the desired value for any instance that we pass as parameter. The result is then outputted in the console. The results in the console can bee seen in the next figure:

image

Demo 2: How do I modify the content of the private member variable with reflection?

We saw before that we need the FieldInfo object instance to do something with our private member fields. If you look carefully on the methods that the FieldInfo provides you, you will notice a SetValue method. Guess what it does? :) You see the code in the next code snippet:

static void Main(string[] args)
{
PrivateClass myPrivateClass = new PrivateClass();

// input from ToString() at the beginning
Console.WriteLine(myPrivateClass);

FieldInfo fi = typeof(PrivateClass).GetField("_privateText", BindingFlags.NonPublic | BindingFlags.Instance);
fi.SetValue(myPrivateClass, "but I'm going to change you!");
Console.WriteLine(myPrivateClass);
}

Most of the code is similar to the previous example. The interesting part lies on line 9 where we are going to change the value of the private member variable to a value that we want. The resulting console output follows:

image

Demo 3: How do I access the content of the private property with reflection?

Retrieving a private property value is similar to retrieving a member variable value. You only need to change the reflection classes used. I think we don’t need to comment the code anymore, since now it should become self-explanatory. The code snippet and figure for our property example follow (note that I’m writing only the relevant parts of the code):

PropertyInfo pi = typeof(PrivateClass).GetProperty("PrivateNumber", BindingFlags.NonPublic | BindingFlags.Instance);
int value = int.Parse(pi.GetValue(myPrivateClass, new object[0]).ToString());
Console.WriteLine("And the private property value is {0}", value);

and here the resulting console output…

image

Demo 4: How do I modify the content of the private property with reflection? 

Now, modifying a property value should not be any issue for you. In our example we are going to write something like this:

PropertyInfo pi = typeof(PrivateClass).GetProperty("PrivateNumber", BindingFlags.NonPublic | BindingFlags.Instance);
pi.SetValue(myPrivateClass, 20, new object[0]);
Console.WriteLine(myPrivateClass);

and there the console output:

image

Summary

In this post you saw how to access private fields and properties by using reflection. This is a very powerful functionality of C# and can become very handy in some scenarios (like in my migration procedure :)). However, use it carefully when you are working with it. The search of fields and properties can become a quite expensive task in execution time.

 

Hope this helps,

Patrick