October 2006 - Posts

SharePoint 2007 - Web Part Property Categorization (or lack of)

I am currently working on a web part for a client.  The web part is pretty simple "looking" but does a lot under the covers.  I have built in validation, not only input validation but also database checks based on the input on the form and the user's identity using some SQL calls.  If all of this succeeds, I am accessing the Reporting Services web services to stream a report to the user, otherwise, displaying an error message.

The web part requires plenty of configuration, such as customizable detailed error messages, labels, button, copy, report name and location, report format, and more.  I will have roughly 12-15 properties by the time I am done (if of course the client doesn't ask for more).

Back in WSS v2 we had an attribute that looked like this (in red):

private string reportPath = "";

[Browsable(true),

 Category("Reporting Services"),

 DefaultValue(""),

 WebPartStorage(Storage.Shared),

 FriendlyName("Report Path"),

 Description("The full Url path to the report in Reporting Services")]

public string ReportPath()

{

    get

    {

        return reportPath;

    }

    set

    {

        reportPath = value;

    }

}

In WSS v3, the list of attributes is a little different.  We have something that looks like this:

private string reportPath = "";

[WebBrowsable(true),

 Personalizable(PersonalizationScope.Shared),

 WebDisplayName("Report Path"),

 WebDescription("The full Url path to the report in Reporting Services")]

public string ReportPath()

{

    get

    {

        return reportPath;

    }

    set

    {

        reportPath = value;

    }

}

I can't seem to locate any other attributes.  Does this mean that the ASP.NET team has removed them?  Can I no longer categorize my custom properties?  Why can the SharePoint team use categories but not us?  Also, I could not locate the default value attribute.  There are other ways to set this in v3, namely in the .webpart xml file, or elsewhere in the code, but why remove perfectly good bits of functionality?  They were just a couple of attributes.

I would love to hear your thoughts on this if you have a possible solution to the categorization issue,  I would rather not have all of my custom properties show up under miscellaneous.

Maybe I am just not looking hard enough.

[EDIT - 11/10/2006]

I found it!

Just add the good old ComponentModel Attribute like so:

[Personalizable(PersonalizationScope.Shared),
WebBrowsable(true),
System.ComponentModel.Category("Reporting Services"),
WebDisplayName("Domain"),
WebDescription("The preceding user's domain.")]
public string SSRSDomain
{
    get { return _SSRSDomain; }
    set { _SSRSDomain = value; }
}

This puts the properties into a collapsible node, like so:

that when expanded looks like this:

I knew it had to be somewhere!

SharePoint BUZZ

Are you part of the SharePoint BUZZ?

I am.

Check it out.

SharePoint BUZZ

SharePoint 2007 - Accessing User Profile properties

For my current project, I have a need to access custom mapped properties of a user profile.  In Office Server 2007, we can create additional profile properties.

We do this in Shared Services Administration by clicking on "User profiles and properties" under "User Profiles and My Sites", and then "Add profile property" under "User Profile Properties":

then

I have gone thru this exercise and added several "custom" properties.  These properties are then mapped to properties in Active Directory (AD) and imported on a schedule.  This import did not work in Beta2, but if anyone is wondering, does in fact work in the Beta2TR.

I have added the "Microsoft.Office.Server" and "Microsoft.Office.Server.UserProfiles" namespaces to my code and cannot seem to find a way to access these values for the currently logged on user.  So, if a value gets stored in one of the many available and unused properties of an AD User, such as "employeeId" using a tool such as "adsiedit.msc" supplied with the Windows Server 2003 Support Tools or by Microsoft Identity Integration Server, how can that property be accessed thru the Office Server 2007 object model if it is mapped to a property in SharePoint, such as BadgeNumber or something like that?

I see an UserProfile object in the SDK but none of the properties seem appropriate for this task.  Is it missing or am I looking in the wrong place.

Well, I just had one of those moments.  I am working on this as I write this post.  Look closely at the "Edit User Profile Property" screen:

There is a "Name" property AND a "Display Name" property.  I had been looking at the wrong property all along as the display name of the property I was interested in was in fact different than the name and in order to access its value you need the name.  At any rate, here is a snippet that will get you the values of the custom properties should you need them.

 

using Microsoft.SharePoint;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;

...

// get the BadgeNumber for this user from the profile store
string _badgeNumber = string.Empty;
SPSite _SPSite = null;

try
{
    // TODO: move this to a configuration setting somewhere
    // get a reference to the current site
    _SPSite = new SPSite("http://SITEURL");

    // get a reference to the context of the current site
    ServerContext _ServerContext = ServerContext.GetContext(_SPSite);

    // get a UserProfileManager
    UserProfileManager _UserProfileManager = new UserProfileManager(_ServerContext);

    // get the UserProfile of the logged on user
    UserProfile _CurrentUserUserProfile = _UserProfileManager.GetUserProfile(System.Web.HttpContext.Current.User.Identity.Name);

    _badgeNumber = (string)_CurrentUserUserProfile["badgeNumber "].Value;  // NOT ["Badge Number"], that was my initial mistake, using display name instead of name :)
}
finally
{
    _SPSite.RootWeb.Dispose();
    _SPSite.Dispose();
}

...

I hope someone gets some use out of this.  I sure will!

Posted 10-26-2006 by Dan Attis | 7 comment(s)
Filed under:
SharePoint 2007 Event Handlers - Some work, some don't.

Since late last year (2005), I have been playing with and testing the SharePoint 2007 betas.  Most of the testing I have been doing has been end user related thru the UI, I haven't done much development.  About 6-8 weeks ago, right before the time that the Beta2TR came out, I started doing some development.  The project I am currently on is a SharePoint 2007 extranet and there is a custom web part I need to write so I thought it was a good idea.  Some of the technologies being used in this project include Active Directory (AD), SQL Server 2005 (SQL 2005), SQL Server 2005 Reporting Services (SSRS 2005), Microsoft Identity Integration Server 2003 (MIIS 2003), Microsoft Internet Security and Acceleration Server 2006 (ISA 2006) and of course, Microsoft Office SharePoint Server 2007 (MOSS 2007).

 

In a nutshell, the piece of this huge puzzle that I want to discuss is adding users to SharePoint groups.  The security model in SharePoint has changed somewhat, simplified you might say, although a little less granular.  MIIS 2003 manages identities.  In our case, extranet users are stored in a SQL Server database somewhere.  There are existing systems in place that manage these users and they do not need to be changed, at least not during this project.  What MIIS 2003 can do is look at these users and then provision AD accounts as necessary.  It can be configured to add/update/disable users in AD as necessary.  Essentially, you write C# code to do this however you want, for example, what pattern to use when creating a username and stuff like that.  MIIS stores previous states so you can see if a user needs to be added, updated or disabled.  It does this out of the box.  What it cannot do out of the box is add users to SharePoint 2007 groups.  The details of this product and all of the things it can do are outside the scope of this post as well as outside the scope of my skill set, so I will leave that up to you, to learn about in your spare time :)

 

The approach we are taking is to write a custom MIIS 2003 rules extension.  Essentially, after MIIS 2003 does something with a user, we have an opportunity to do something else.  In this case we will be calling into the SharePoint web services and adding/removing user to specific groups based on properties stored in the MIIS metaverse and AD.  This approach will work fine, but led me to think of possible alternatives.

 

Last week I attended a MindSharp SharePoint 2007 Developer summit taught by Todd Bleeker.  Todd is an excellent speaker and it was 5 days of some darn good developer training.  We covered a boat load of topics.  One of the topics we covered was event handling.  Event handling in SharePoint 2007 has dramatically improved in this version.  In v2 (2003) we only had synchronous event handlers, meaning we could only write code to do something "after" something happened in SharePoint.  Now, in the new version we also have asynchronous event handlers, meaning we can write code to do something "after" something happens and also "before" something happens.  This is a huge improvement and will be welcomed with open arms by SharePoint developers.  You might be saying to yourself, wow, Microsoft actually listened.  Yes, they did, but there are, of course, some caveats.

 

We now have access to many new events.  I have tested many and many do not work yet in the Beta2TR (I hope they fix them!).  I'll leave that for another post.  In the previous version, we could attach an event handler to a specific list.  We can't do that anymore.  Now, we have to attach an event to a list template.  The SDK defines many list templates, for example Announcements are 104.  Check out the following screen shot.

 

 

I tested the "Deleting" event.  This event fires right before an item gets deleted.  I successfully tested this event on an announcement list and prevented items from being deleted; actually, what happened is irrelevant, the point is that the code worked and did what it was supposed to do.  I started to think about how I could apply this on my current project.  I had an epiphany and thought hey, if I can write an event that fires after items are added/updated/deleted from an announcement list shouldn't I be able to do that for the user list as well?  It is just a list.  It should have events.  Most SharePoint developers know that when if you view source on a list view there are a bunch of hidden fields towards the bottom of the page.  One of those fields is the list template id.  If I do this for an announcements list I see the following line:

 

ctx.listTemplate = 104;

 

This is the list template id used when attaching events.  So an event attached to this list template id would fire for every announcements list.  I could filter by list name or id in my code if I wanted to to give me the same functionality of hooking an event up to a particular list,  a little less performant as it would be checking on every list.  Also worth mentioning is that this event handler can be scoped to a single site if needed so it wouldn't be used on all announcements lists in a farm necessarily.

 

Since, the users are stored in a list, I thought I would check to see what the list template id was on a that list, then, in theory, I could hook events up to that list.  Here is the HTML markup snippet from a view source on that page:

 

ctx.listTemplate = 112;

 

Well golly, I don't see that list template id in the SDK screen shot above.  That tells me that this may not be supported or if it is it isn't documented yet.  I wonder how many other "secret" ids there are in the product.  Just for fun, I started poking around the content database to look for the rest of these list template ids.  I spent about 15 minutes on this task and decide to give up for the time being.  I couldn't find anything and Law & Order was more interesting.  What I tried doing was change the list template id in my working event handler from 104 (Announcements) to 112 (All People).  I then went and deleted a user from the site collection.  I also made sure that my event handler was scoped correctly so it would fire for this web site.  To make a long story short, well, shorter, after  muchos testing, the event did not fire.

 

I am disappointed but will continue to test and research this issue as newer builds come out.  If anyone has any input/ideas, please let me know!

Posted 10-23-2006 by Dan Attis | 6 comment(s)
Filed under:
I now have Live Writer

So in theory I have run out of excuses to not blog, so this is a test post everyone can ignore :)

More to come.

Posted 10-20-2006 by Dan Attis