Sunday, September 30, 2007

SPWeb.Groups vs. SPWeb.SiteGroups

Here's a weird one that maybe someone will help me out with some day (you know once people actually start subscribing/reading to this blog). I'm working with the SharePoint Object model and I want to get at all the Groups within a given Site. So we write some code that looks a little like this:

using (SPSite topLevelSite = new SPSite(ConfigurationManager.AppSettings["ForumSharepointInstanceUrl"]))
using (SPWeb rootWeb = topLevelSite.OpenWeb())
foreach (SPGroup group in rootWeb.Groups)
//go do something clever...

If you've run code that's similar and you've found that certain groups are missing from the SPWeb.Groups collection don't feel like you're alone. As it turns out (at least from what I can discern) the SPWeb.Groups returns all the groups within the web that have at least one permission set. The SPWeb.SiteGroups however will return ALL groups. I have no idea why. I also couldn't find anything of use about the topic on the MSDN. I've also found blog entries from people who couldn't find specific SPUser objects when digging in the SPWeb.Users vs SPWeb.SiteUsers collections. Their complaint was similar that the SPWeb.Users collection would only find users who had already logged into the site.

Summing it up: Use SPWeb.SiteGroups, SPWeb.SiteUsers etc... and ask someone who has some real SharePoint chops.

Still Confused,

Saturday, September 29, 2007

AllowUnsafeUpdates, a Sharepoint Object Model gotcha

The other day I was trying to programatically add group to SharePoint via the object model and a confusing exception would continue to get thrown. This same exception could happen whenever you are trying to add an SPUser, SPWeb, Group etc... to an existing collection via the SharePoint object model.

I would run some code that looked a little like:

SPMember owner = rootWeb.Users["SomeUserName"];
SPUser user = rootWeb.Users["SomeUserName"];
rootWeb.SiteGroups.Add(groupName, user, null, description);

And the following exception would get thrown:

System.Runtime.InteropServices.COMException: The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.

After digging around I discovered that you need to set SPWeb.AllowUnsafeUpdates = true. I have yet to find out the implications of this setting although the MSDN states that

"Setting this property to true opens security risks, potentially introducing cross-site scripting vulnerabilities."
The good news is that after you call Dispose on your SPWeb object and get a new one the setting is reset to false.

Friday, September 21, 2007

Ajax in MOSS via the Update Panel

I'm currently doing a lot of ASP.NET development inside MOSS 2007. On this current project we've been doing the most of our RAD outside of SharePoint and then porting our ASP.NET application inside a MOSS instance for integration. Needless to say, like so many developers working with MOSS, I've had an interesting time troubleshooting a litany of errors that seem to come up working inside this new framework.

Today's save comes from Mike Amerlaan who's figured out a fairly critical hint that's needed to get Update Panel's to work inside a MOSS site.

Prior to discovering Mike's fix I would be able to post back (inside an update panel) ONCE after which all postback's on the page became non functional.

Essentially this is because WSS emits submit wrapping javascript that tampers with how your page submits. It does this to ensure that urls that involve double byte (read unicode) characters post back appropriately.

To get your update panels working you're going to have to remove this script. You can disable it by emitting the following javascript:

spOriginalFormAction = document.forms[0].action; _spSuppressFormOnSubmitWrapper=true;

You can of course do this by using either the ScriptManager or the Page.ClientScript.RegisterStartupScript. I'm pretty sure you'll be able to figure the rest out.

Besides that you pretty much do what you would expect to do to get UpdatePanel's working inside MOSS.

  1. Install the Ajax extensions on the host machine
  2. Migrate the web.config settings that tee up all the ajax controls/http handlers/http modules
  3. Add a tag to each page (or master page) that you want to use it in.
  4. Add you update panels around some postback event.
And that's it! Voila you're done. Now your MOSS site feels a little bit less like a stock MOSS site.

Happy Coding,