How to: Programmatically set the target audience on a web part
Posted
Tuesday, November 10, 2009 1:51 PM
by
CoreyRoth
I’ve been working with audiences again, so I recently wanted to set the target audience of a web part. Sure anyone can set it in the UI, but I want to automate my deployment, so I wanted to do it programmatically using a feature receiver. When I first started looking for more information on how to do this, I wasn’t finding exactly what I needed and I did find some conflicting information. To be clear about what I am talking about today, I am discussing how to target a web part to an audience in MOSS that was defined and compiled in the SSP. Since I couldn’t find much info on the Internet, I posted something on twitter and I got a response from Randall Isenhour (@sharepointdev) on the SharePoint SDK team who referred me to Jim Crowley. Thanks to both of them for pointing me in the right direction.
For today’s discussion, we have two audiences: Audience 1 and Audience 2 as shown below.
You might think that you would apply an audience to a web part using the AudienceManager class but that in fact not the case. We actually do this by making use of the AuthorizationFilter property on the WebPart class. The problem is that this property takes a syntax that not too many people fully understand. Luckily, Jim pointed me to this post by Gary Lapointe where he demystifies how the string is created. The AuthorizationFilter property can be used to specify a GUID to an audience. However, it can also be used to specify an LDAP distinguished name or a SharePoint group. In this case we only care about the GUID to the audience. All three can be specified in one string and are delimited with a double semi-colon (;;). The first group is where you specify Audience Ids, the second is the distinguished name, and the last is the SharePoint group. You don’t have to specify all three though, we’ll only be specifying the audience today.
Let’s take a look at some code. For today’s example, we can assume that we are writing code inside a FeatureActivated event handling method. I’ll be getting a reference to an SPWeb object from there. I am simplifying this example some because I only have one web part on my page and so I am just referencing it with an indexer value of 0. You will want to change this to some code to find the appropriate web part on your page. You’ll also need references to Microsoft.SharePoint, Microsoft.SharePoint.WebPartPages, and Microsoft.Office.Server.Audience.
using (SPWeb currentSite = (SPWeb)properties.Feature.Parent)
{
using (SPLimitedWebPartManager webPartManager
= currentSite.GetLimitedWebPartManager("default.aspx", PersonalizationScope.Shared))
{
AudienceManager audienceManager = new AudienceManager(ServerContext.Current);
webPartManager.WebParts[0].AuthorizationFilter
= string.Format("{0};;;;", audienceManager.GetAudience("Audience 1").AudienceID);
webPartManager.SaveChanges(webPartManager.WebParts[0]);
}
}
I then use the SPLimitedWebPartManager against the page I am working with (in my case default.aspx). The AuthorizationFilter takes a GUID, so I need to look up the GUID for my audience using the AudienceManager. It has a GetAudience method which takes a parameter which is the name of the audience (Audience 1). I can then use the AudienceID property to write the GUID into the AuthorizationFilter property followed by “;;;;". We have to specify the four semi-colons since other types of filters can be applied here in this case. My AuthorizationFilter string would look something like this.
D2E05D3D-633F-4f0b-BA47-64E0F6A40A74;;;;
The last thing, you have to do is call SaveChanges on the SPLimitedWebPartManager object and pass a reference to your web part. I’ll go ahead and point out now that, there is no error checking in the code above. If you are to do this, you would want to add checks to verify that the page, web part, and audience exist to say the least. If all goes well, when you view your page, you should be able to verify that the target audience is set like below.
Now, I’m sure you know that you can target more than one audience on a web part, right? It would be bad form for me not to show you how to do that, so here is what that looks like. The key is using a comma to delimit each audience. Here is what that code would look like.
webPartManager.WebParts[0].AuthorizationFilter = string.Format("{0},{1};;;;",
audienceManager.GetAudience("Audience 1").AudienceID,
audienceManager.GetAudience("Audience 2").AudienceID);
The result would then look like this. SharePoint shows them delimited with a semi-colon when viewing them in the UI.
As you can see, setting a target audience is actually quite easy once you know the syntax of the AuthorizationFilter string. I have also found that sometimes when messing with audiences, that the Target Audiences property will completely disappear from the UI. Although, I’m not sure what the cause of this is, I have found that you can bring it back by rebooting. I have also found that you can restart the Windows SharePoint Services Administration service followed by an iisreset and it will come back as well.