Audiences field in the Web Part settings pane
In the first part of this article we discussed how ASP.NET Profiles can help us extend SharePoint Server 2010 Audiences capabilities with targeting content to anonymous users. We discussed what ASP.NET Profiles are, how they work and how they can be configured with SharePoint Server 2010. In this part of the article we will extend the SharePoint Server 2010 Audiences so that they can make use of the data stored in ASP.NET Profiles.

How does content targeting in SharePoint Server 2010 work?

SharePoint Server 2010 ships with the content targeting capability which allows you to display content to specific groups of users. This mechanism is based on Audiences: groups of users who fulfill certain criteria such as being over certain age or having some specific interests. Every time a change is made to the rules that make up an Audience, this Audience has to be compiled. This can be done either manually or automatically by a Timer Job that is being run daily by default. Compiling Audiences allows SharePoint Server 2010 to scale better as it doesn’t have to resolve the membership on run-time which could have a serious performance penalty in large deployments.

The other piece of the puzzle that allows SharePoint Server 2010 to conditionally show content is the Runtime Filter. Runtime Filter is a mechanism that is being called to determine if a Web Part should be rendered or not. SharePoint Server 2010 ships with a Runtime Filter that uses information about Audiences to determine whether the current user belongs to a certain Audience and if the Web Part should be rendered or not.

SharePoint Server 2010 allows you to specify one Runtime Filter per Web Application. Although this might seem limiting at the first glance, the good news is that the most important building blocks of the standard Runtime Filter shipped with SharePoint Server 2010 are public and can be used in your own implementations, what allows you to extend the standard content targeting capabilities of SharePoint Server 2010 without too much work.

Targeting content for anonymous users using ASP.NET Profiles

In the sample scenario created for the purpose of this article we will create three pages which will represent three different gaming consoles: Xbox, wii and PS3. Then on the home page we will add a special offer of new Xbox accessories for anonymous visitors of who we think that they are interested in Xbox.

SharePoint Server 2010 Audiences: also for anonymous users

The first step to be able to target the content to anonymous users is to define an Audience to whom we want to target the content. Standard SharePoint Server 2010 Audiences use rules based on SharePoint Server 2010 User Profile Properties to determines whether a user belongs to a certain Audience or not. Although we cannot use SharePoint Server 2010 User Profiles with anonymous users, we can still create empty Audiences and use that information to target content to anonymous users. By creating an Audience with the same name as the name of the ASP.NET Profile Property you can easily determine if an anonymous user belongs to the specific Audience or not. Although this approach is not ideal, it allows you to easily create Audiences that can be used for both anonymous and authenticated users using the standard SharePoint Server 2010 user interface.

Preparing the website

For the purpose of this scenario we will use the same Site Collection we used in the first part article as it has all the plumbing that we need in place.

Configuring the LikesXbox Audience

The first step is to create an Audience for our visitors who like Xbox. For this go to Central Administration > Manage service applications > User Profile Service Application > Manage Audiences. On the View Audiences screen click the New Audience button to create a new Audience.

Mouse cursor pointing at the New Audience links on the View Audiences screen in SharePoint 2010 Central Administration

Let’s call the Audience LikesXbox – just as our ASP.NET Profile Property is called and specify a user who will own this audience.

The Create Audience screen with the name and the owner of the new Audience filled in

On the next screen, when asked about creating an Audience rule you can click the Cancel button. Because anonymous users don’t have any properties stored in SharePoint there is little point of defining rules. Specifying rules would be useful though, if we were using the same Audience for both authenticated and anonymous users.

At this moment you should have an empty Audience created which can be used for targeting content to anonymous users.

The LikesXbox Audience displayed in SharePoint 2010 Central Administration

Configuring the product pages

The next step is to create a Publishing Page for every gaming console in our shop.

Site menu showing three options one for every console

The next step is to mark visitors who like Xbox so that we can target Xbox content to them. In this scenario we will use a simple rule: everyone who visits the Xbox page will be marked as a person who likes Xbox.

In order to mark visitors who like Xbox we will reuse the Write Web Part we created in the previous article. By adding it to the page, it will automatically set the LikesXbox flag on every anonymous visitor who will open the page. Just to finish it off let’s set the Web Part’s Title to LikeXbox and set the Chrome Type to None as we don’t want the Web Part to be visible.

The Write Web Part on the Xbox page in Edit Mode

Let’s Publish the page to be sure that it’s available to anonymous users.

Adding content targeted to an anonymous Audience

The next step is to add a Web Part to the Games Heaven page that will show some content only to the visitors who like Xbox. For this go to the Games Heaven page and a new Content Editor Web Part (CEWP) to it. Set its Audience to LikesXbox.

The Audience of the newly added Content Editor Web Part set to LikesXbox

In the Content Editor Web Part add some content. This content will be visible only to visitors who match the LikesXbox Audience. When you apply the changes by Publishing the page you will notice that the CEWP isn’t being displayed anymore. This is being caused by two things. First of all the LikesXbox Audience that we configured earlier didn’t contain any rules and therefore didn’t contain any users. Additionally we are still missing the most important piece of the puzzle which is an extended version of the Runtime Filter that SharePoint Server 2010 ships with, which is capable of using the information about Audiences and combined with the information from ASP.NET Profiles can determine whether the content should be displayed to the current user or not.

Extending the SharePoint Server 2010 Runtime Filter with support for anonymous Audiences

As you should know by now, targeting content using Audiences in SharePoint Server 2010 works thank to the AudienceManager Runtime Filter. The Runtime Filter is a component which is responsible for matching the Audiences that the specific content is targeted to with the Audiences where the current user belongs to and conditionally showing the content using that information.

Although the AudienceManager is public it cannot be extended. The CheckRuntimeRender method, responsible for determining whether the content should be rendered or not, hasn’t been marked as virtual what makes it impossible for you to override in a Runtime Filter that would derive from the AudienceManager. Luckily the most important pieces of the standard AudienceManager belong to the public API and can be used in your custom Runtime Filter so that you can easily extend the SharePoint Server 2010 content targeting capabilities without too much work.

The following code snippet presents a custom Runtime Filter that targets content for authenticated users using the standard SharePoint Server 2010 Audiences and uses information from ASP.NET Profiles for anonymous visitors.

public class AnonymousAudienceManager : IRuntimeFilter2
{
    #region IRuntimeFilter2 Members

    public IToolPaneControl GetToolPaneControl()
    {
        AudienceEditor editor = new AudienceEditor();
        editor.Types = AudienceEditor.AudienceType.SharePointGroup | AudienceEditor.AudienceType.DL | AudienceEditor.AudienceType.GlobalAudience;
        editor.MultiSelect = true;
        editor.AllowTypeIn = true;
        return editor;
    }

    #endregion

    #region IRuntimeFilter Members

    public bool CheckRuntimeRender(string IsIncludedFilter)
    {
        if (SPContext.Current != null && SPContext.Current.Web.CurrentUser != null)
        {
            return AudienceManager.IsCurrentUserInAudienceOf(IsIncludedFilter, true);
        }
        else
        {
            bool render = false;

            if (HttpContext.Current != null && SPServiceContext.Current != null)
            {
                System.Web.Profile.ProfileBase profile = HttpContext.Current.Profile;
                if (profile != null)
                {
                    string[] globalAudienceIDs = null;
                    string[] dlDistinguishedNames = null;
                    string[] sharePointGroupNames = null;
                    int num = AudienceManager.GetAudienceIDsFromText(IsIncludedFilter, out globalAudienceIDs, out dlDistinguishedNames, out sharePointGroupNames);
                    if (num > 0 && globalAudienceIDs != null && globalAudienceIDs.Length > 0)
                    {
                        AudienceManager am = new AudienceManager(SPServiceContext.Current);

                        foreach (string audienceId in globalAudienceIDs)
                        {
                            Guid g = new Guid(audienceId);
                            Audience a = am.Audiences[g];
                            if ((bool)profile.GetPropertyValue(a.AudienceName))
                            {
                                render = true;
                                break;
                            }
                        }
                    }
                }
            }

            return render;
        }
    }

    public System.Collections.ArrayList InitializeStrings(System.Globalization.CultureInfo cultureInfo)
    {
        return new ArrayList { "Audiences:" };
    }

    public bool IsFilterActive()
    {
        return true;
    }

    public string ValidateIsIncludedFilter(string persistedString)
    {
        return persistedString;
    }

    #endregion
}

In order to include the above code snippet in your project, you will need a reference to the Microsoft.Office.Server and the Microsoft.Office.Server.UserProfiles assemblies which are used by the SharePoint Server 2010 AudienceManager.

First of all the GetToolPaneControl method is responsible for returning a control that is added to the Web Part’s Edit Pane and which allows you to select the Audiences to which the content of the Web Part should be targeted to. To keep this example simple we use the standard AudienceEditor control. Although creating your own control would add some extra complexity to the project it would give you some extra flexibility and would allow you to handle anonymous Audiences separately rather than creating empty SharePoint Server 2010 Audiences.

Next is the CheckRuntimeRender method which determines whether the content should be rendered or not. The IsIncludedFilter parameter contains a string representation of all Audiences that has been configured in the Web Part. If the user is authenticated, standard SharePoint Server 2010 Audiences are being used. For anonymous users the information from the ASP.NET Profile is being retrieved and used to determine if the user belongs to one of the Audiences specified in the Web Part.

The InitializeStrings method is responsible for returning the right label for the given culture that will be displayed above the Tool Pane Control. In this example we’ve used a hard-coded string but in a real-life scenario you might want to replace it with a call to a Resource Manager – especially if you’re dealing with multilingual solutions.

The IsFilterActive method determines whether or not the Runtime Filter is enabled. The SharePoint Server 2010 AudienceManager checks in this place if the User Profile Service Application has been configured and is enabled. Because we’re dealing with anonymous Audiences such check would cover only a half of the story. In most situations Anonymous Audiences are specific capability that is added for specific scenarios. That’s why always enabling the Runtime Filter is sufficient. If you need to add some extra flexibility to the AnonymousAudienceManager you might implement here two different checks: one for anonymous and one for authenticated users.

Last but not least is the ValidateIsIncludedFilter method which is responsible for validating the string representation of selected Audiences. Because we’re using the AudienceEditor control which does that automatically, returning the same string as passed through the persistedString parameter is sufficient.

Now that everything is in place, it’s time to register the AnonymousAudienceManager with the Web Application. You can do this by replacing the values of the Assembly and Class parameters on the RuntimeFilter element in the configuration/SharePoint section of web.config.

Tip: If you’re using Community Kit for SharePoint: Development Tools Edition (CKS:DEV) you can quickly copy the full name of the assembly by clicking the project right button and choosing Copy Assembly Name from the menu.

Copy Assembly Name menu option highlighted in the project context menu in Visual Studio 2010

AnonymousAudienceManager registered in web.config

This was the very last configuration step required to implement anonymous Audiences in SharePoint Server 2010. At this moment everything is in place and can be tested.

Testing Anonymous Audiences with SharePoint Server 2010

To test our implementation of Anonymous Audiences with SharePoint Server 2010 let’s first go to the Games Heaven homepage as an anonymous visitor. The first time we visit the page no information about us is stored in the ASP.NET Profile and therefore we see only the standard text.

Games Heaven homepage showing only the default content

Now let’s navigate to the Xbox page. ASP.NET Profile Provide will now register that we like Xbox: the LikeXbox property is being set to true.

When we go back to the home page of the Games Heaven site now, we should see an advertisement of a new Xbox accessory.

Xbox advertisement displayed for anonymous users who like Xbox

Future considerations

In this article we covered the concept of extending SharePoint Server 2010 content targeting capabilities with targeting the content to anonymous users. Although this article provides you with a step-by-step description of how to create a simple solution there are still some things that you should take into consideration before implementing this concept in a real-life solution.

Setting values for properties

Targeting content itself isn’t as difficult as determining when exactly the content should be displayed. In our sample we created a simple boolean property that was set on the first visit to the Xbox page. Unfortunately in real life setting such properties may get more complex and setting a property might be triggered by not one but multiple visits to the same or even a combination of different pages! As the properties are the main driver of successfully targeting the content you have to spend enough time on creating a clear strategy of how you will target the content, what the triggers will be and what’s most important – how will you keep it all manageable.

Authenticated vs. Anonymous Audiences

In our sample we used a clear separation of authenticated and anonymous users. This made it easy for us to provide two different mechanisms of targeting content. In a real life scenario however, this might be a little more complicated as you might provide your visitors with the ability to create a profile, and as soon as they login they are not anonymous anymore! So instead of focusing on the authenticated vs. anonymous scenario you might want to consider the way the user has authenticated (NTLM vs. Forms) or maybe even using claims in case they are multiple ways for the users to log in (Forms, Live ID, Open ID, etc.).

This takes us to the next thing that you should consider which is handling the process of profiles migration. By default ASP.NET Profiles handle authenticated and anonymous profiles separately, meaning that as soon as the user logs is, the profile of the authenticated user is being used instead of the anonymous profile. Luckily the ASP.NET Profile Provider gives you the ability to implement a solution for migrating an anonymous profile to its authenticated version.

Keeping it all manageable

Creating the initial solution isn’t that complex. As you have seen throughout this article there are a few things that you have to configure and some limited amount of custom code is involved as well but all of that isn’t really as complex as keeping the whole process of targeting content manageable. SharePoint Server 2010 doesn’t natively support targeting content to anonymous users, meaning that you will need to provide content managers with some user interface that will make it easier for them to create and manage anonymous audiences.

Summary

In this article we discussed how you could extend standard SharePoint Server 2010 content targeting capabilities with targeting content to anonymous users. Although this article presents you a working solution it’s a demo of the capabilities that SharePoint Server 2010 and ASP.NET offer you as applications platforms rather than a turn key solution. The concepts discussed in this article are there to show you how you could extend content targeting capabilities of SharePoint Server 2010 and what are the things that you should consider before you implement such solution in a real-life scenario.

Technorati Tags: ,