Discussing the nuts and bolts of software development

Friday, September 12, 2008


Bridge SharePoint - User Profiles and User Profile Properties (part 2 of 2)

As we have found out in part 1, SharePoint can manipulate data using the user profile management objects and can accept data from external sources. Using these two features apart we have two limited tools with limited usage, but using them together gives us a powerful, flexible and efficient method of storing and using data from any internal or external resource.

It’s time to see this solution to our problems in action.

Code example of getting/setting the profile property from a C# application

The concept is the same for any source of information (web services, web applications, etc.):
Get the user’s profile->Get the required profile property->Get/Set profile property value

Code example: (note that to access profile properties, this code must run with elevated privileges)

string value;

// Change the site address for different deployment environments
// Note: WIN2003STD is a place holder for your environment, usually your server name
SPSite site = new SPSite("http://WIN2003STD/");
SPWeb web = site.OpenWeb();

// Get the profile manager object for the site
UserProfileManager profileManager = new UserProfileManager(ServerContext.GetContext(site));

// Use the username from the User Information Item to get the full profile of an user
UserProfile user_profile = profileManager.GetUserProfile(System.Web.HttpContext.Current.User.Identity.Name);

// Get the required profile property value from the profile
value = user_profile["MyProperty"].Value.ToString();

catch (Exception e)
return "Error getting user info: " + e.Message.ToString();

user_profile["MyProperty"].Value gets or sets the profile property value.

This is a very convenient way of using profile properties to store required information for each user. Properties can be set as read-only or not to appear in the user’s profile, which gives you even more control.

System.Web.HttpContext.Current.User.Identity.Name returns the username (the login username) and it is used in the code example above to get the profile of the currently logged-in user.

Tools You Never Knew You Had… (and what to do with them now that you’ve wised up!)

With this simple solution to getting/setting a user’s profile property value, endless opportunities are now at hand. This small code snippet helps developers control, validate and use values stored for each user, without corrupting the database or resorting to other more complex and error-prone solutions.
For those not needing to use an external application to get information from the users, a custom SharePoint web application can be developed and deployed on SharePoint. This way all the controls offered by ASP .NET or custom controls can be used to perform required operations on the data before it’s stored.

External applications running on the server can access this information the same way, so a bridge between SharePoint and applications like web sites, game servers, messaging apps, etc. can be easily created.

SharePoint Complications, As Usual

Watch out that the profile property might be set as read-only in SharePoint. Even if it’s the case however, the above code should still be able to access the profile because it’s running with elevated privileges. So if there is a situation in which the user is allowed to see the data but only modify it by using a service (like a web application or web service), this is a good way of doing it.

Another gotcha is that the code above can only be used on the SharePoint server machine. This is due to the framework that SharePoint uses. To get information or to change data from a network on internet location, a SharePoint custom web service or web application can come in handy. Other ways of passing information will work too, like server-client applications, as long as the part running the above code is on the SharePoint server machine.

So we now have a way to store data and manipulate it according to our needs. We can control it, we can validate it and most important of all, we decide how the user interacts with the data.

We’re now ready to start doing some serious SharePoint development!

Labels: , , , , ,

Wednesday, September 10, 2008


Bridge SharePoint - User Profiles and User Profile Properties (part 1 of 2)

There is a constant need in SharePoint feature development to bridge SharePoint 2007 with other web applications. In order to create such a bridge, a variety of user information must be stored in the SharePoint database.

Warning: Do not tamper with the SharePoint database! No matter how tempting it is!

Although this might sound as simple as a small SQL application, tampering with SharePoint’s database could lead to disastrous results and even complete and irreversible server crashes, since many of SharePoint’s recovery features rely on the database being intact. “Feeding” information to SharePoint through its database is unadvisable and sometimes very hard to do, mainly due to the complex structure of the database.

Fortunately there is a built-in solution to this problem that is both simple and efficient: User Profiles and User Profile Properties.

In this post we will see how SharePoint’s user profiles and profile properties can help us do our job fast and easy without worrying about crashing the server or breaking more features than we create.

Let’s start with the storing information problem.
Many developers have already considered using Profile Properties as way to store the required data, but have given up on using them due to their limitations (limited validation, control, variety). Controlling the user’s input and making sure that the values are correct is essential in any bridge, and often auto-generated values based on that data are necessary. SharePoint can only do so much, and this is usually the main reason why developers avoid using the custom profile properties.

Solution: Manage information using the Microsoft.Office.Server.UserProfiles namespaces.

SharePoint Server 2007 stores user profiles in SQL Server, but the information can be imported from other data sources, such as:
· Active Directory
· Lightweight Directory Access Protocol directories (which is not Active Directory)
· Databases
· Enterprise applications (such as SAP or PeopleSoft) by defining a Business Data Catalog connection
· Web applications
· Custom SharePoint web services
· Standard .NET applications, etc.
The main classes are found in the Microsoft.Office.Server.UserProfiles namespaces. The assembly is Microsoft.Office.Server.dll found in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI.
The main objects to handle information within the User Profile store are:
Allows you to access profile properties, the My Site, personalization links, and so on.

Gives access to a collection of UserProfile objects and allows you to create, edit, and retrieve user profile objects and properties from the user profile store.

Manages the user profile configuration.

Note: In order to manage data in a custom user profile property, the property must be first created. You can use the following steps to create a profile property:

1. Start > Administrative Tools > SharePoint 3.0 Central Administrator
2. In the left panel, under Shared Services Administration, click SharedServices1
3. Click User Profiles and Properties
4. Under User Profile Properties, click Add Profile Property
5. Fill in the required data and click OK

Now that we know that SharePoint accepts data from external sources and that it stores individual user values in user profile properties, it’s time to put the two together and find out how to store user data in profile properties from external data sources. This is the topic for part two of this post: Getting/Storing user data from external sources.

Labels: , , , ,

Thursday, September 04, 2008


SharePoint says "Unknown Error"

ERROR: Only Content controls are allowed directly in a content page that contains Content controls.

By default, SharePoint doesn't seem willing to share some of its internal errors with developers opting instead to use a generic "Unknown Error" page. The informative (and I use the term loosely) error string above wasn't displayed in the browser until the file C:\Inetpub\wwwroot\wss\VirtualDirectories\80\web.config was modified to disable custom error messages.

By changing <SafeMode CallStack="false" ...> to <SafeMode CallStack="true" ...> and changing <customErrors mode="On" /> to <customErrors mode="Off" />, the generic error page is replaced with a more detailed error message and maybe even a callstack.

As for the error above? It was caused by a comment that had been added to an .aspx file. For some reasons, comments were not allowed because they didn't qualify as "content controls".

This page is powered by Blogger. Isn't yours?