The perils of storing SPWeb metadata
On Friday while searching for how to store metadata in a web object, I was looking through the MSDN documentation for the SPWeb class. The SPWeb.Properties property looked like just what I needed. As I was reading the detailed description, I found this gem:
RemarksThis property returns only a subset of the metadata for a Web site. To get all the metadata, use the AllProperties property.
Huh. So why does it return only a subset? What subset does it return, a random selection perhaps? If it only returns a subset, shouldn’t they have named it SomeProperties or perhaps NotAllProperties instead?
The MSDN docs din’t explain anything, but Google always knows the answer. It turns out that the Properties property (besides having a confusing name) represents an older mechanism for storing metadata. It has been replaced by the newer AllProperties property, but is still present for backwards compatibility.
Properties returns a SPPropertyBag object, a custom type which can store key/value pairs — keys are case insensitive and are converted to lowercase when added. AllProperties on the other hand uses a standard Hashtable collection to store its key/value pairs and has case sensitive keys. Furthermore, the SPPropertyBag class has its own Update method which updates the database with any changes to the collection. The AllProperties collection on the other hand is saved by calling the Update method of the SPWeb object.
To add to the confusion, keys added to Properties are also stored in AllProperties, but not the other way around. This explains the “returns only a subset of the metadata” part of the property description.
But it doesn’t stop there — no, joy of joys, there’s more! In SharePoint 2010, four new methods were added to the SPWeb class.
Thanks, that’s so very helpful. Four new methods that deal with SPWeb metadata, and no description or explanation. Which collection do they store their data in? Properties? AllProperties? Both? Their own, separate collection?
Thankfully PowerShell, which I’m just learning to use, allowed me to quickly test the behaviour of the new methods. Perhaps not unexpectedly, they read and write to AllProperties, the more recent of the metadata collections.
It seems like all this has the potential to cause great confusion if not all developers on a team use the same collection to store their metadata. Especially the way Properties updates AllProperties but not vice versa, and the fact that the new methods are not documented, nor is the distinction between Properties and AllProperties explained properly. Luckily though, as I have just recently started to work with SharePoint, this issue hasn’t had the chance to cause me any grief yet… on the contrary, the process discovering all of this on a Friday afternoon proved to be a great source of entertainment.
Getting around GAC problems when you deploy SharePoint solutions with PowerShell
In a previous post I wrote about how to replace the Visual Studio deployment steps with your own PowerShell script, which allows you to take full control over how you deploy solutions to your development machine.
In addition to enabling more advanced deployment scenarios, this allows you to use the same scripts when you deploy locally and to your test and production environments. The Visual Studio deployment engine is great – but it’s almost too helpful. It cleans up everything for you, automatically fixing all kinds of deployment conflicts.
This creates an artificial environment. In test or production, it’s possible that you never want to actually retract and reinstall your solution, just update it, and if you do reinstall it, Visual Studio is not around to fix deployment conflicts for you. So you may be headed for a nasty surprise when you take your solution to a test server for the first time, and discover there are all sorts of upgrade scenarios to consider. (For instance, it’s really difficult to overwrite existing files.)
Make your own PowerShell scripts for SharePoint deployment in Visual Studio 2010
The SharePoint developer tools in Visual Studio 2010 allow you to deploy the solution you’re working on directly to a SharePoint site. The deployment steps are both configurable and extensible: You can choose which deployment steps you want to perform (add solution, activate features, etc.), and it is also possible to define your own custom deployment steps in a Visual Studio extension.
The configuration options are fairly limited. For instance, you can choose to “activate features” as part of the deployment. But what if you have multiple features in your solution, and you normally only want to activate some of them? You could move the rest into their own solution, but that’s an ugly way to solve this. What then?
Changing the disk location of uncustomized (ghosted) pages
Files that have been added to SharePoint can be either customized or uncustomized. Customized means the data lives in the database. Uncustomized means the entry in the database just points to a location on the disk. When you change an uncustomized file on a particular site, for instance using SharePoint Designer, it becomes customized, and is moved into the database.
“The language-neutral solution package was not found”
We sometimes get this error when deploying SharePoint 2010 (beta 2) solutions from Visual Studio 2010:
Error occurred in deployment step ‘Retract Solution’: The language-neutral solution package was not found.
We don’t know why this happens, possibly some beta problem, but one solution is to call the Delete method on the solution directly, using PowerShell:
(get-spsolution mysolution.wsp).Delete()
You can also run get-spsolution without parameters to see which solutions are currently installed in the farm.
Getting multiple layers of web.config modifications to live together
In our SharePoint 2010 solutions we have web.config modifications that are standard, and custom modifications that are later added on top of the standard ones. This article describes a way for multiple levels of modifications to live together, in a way that supports upgrades of the standard modifications without destroying the custom ones.
Before you read this you should be familiar with the web config modification framework in SharePoint. It’s important never to modify SharePoint web.config files directly, especially when you’re deploying your solutions to a farm environment.
Using the FeatureUpgrading event to upgrade features
In SharePoint 2010 there is now a way to control how features are upgraded from one version to another. Here’s how to get it working, using the new FeatureUpgrading event in the feature receiver class.
Time to replace stsadm with PowerShell
One thing in SharePoint 2010 I appreciate as a developer is the close integration with PowerShell. PowerShell is the result of a bit of Unix envy at Microsoft. Unix systems have had good command-line tools and scripting languages since the dawn of time. Windows had cmd.exe, which was inferior 20 years ago when it was known as MS-DOS, and hasn’t been changed since.
But when PowerShell finally did arrive, in 2006, it was as good as the Unix alternatives, and in one important way superior: Object piping. PowerShell allows you to string commands together and pipe the results of one as input to the next, as .Net objects. In a SharePoint 2010 context, that allows you to do this:
BCS first impressions
The right way to think of Business Connectivity Services in SharePoint 2010 is probably as a pipe you can attach your data to, and, once you’re connected, that pipe can take you anywhere within SharePoint and Office. One shouldn’t be taken in by the hype here – this is the sort of functionality Microsoft often oversells as a magical tool for anything – but within the limitations BCS looks like a really useful technology for anyone who has data in various systems that they want to display in a SharePoint context. Which is probably everyone.
There are four approaches to BCS, two of them are comparatively easy and can be used with SharePoint Designer, and the other two are more difficult and are used with Visual Studio.
Getting the current users language programmatically
Running with multilingual sites in SharePoint 2010, it can often be relevant to programmatically figure out what language the current user has selected. In this case I am running an english site, where I have changed the language for my user to german.
There are several SharePoint objects one can consider to look in, for example SPWeb or SPUser to get the users selected language. In the picture below I have added a screenshot of a debugging session with the various relevant values I found.
In order to get the language selected by the user, you will have to access the property System.Globalization.CultureInfo.CurrentUICulture. Properties like SPContect.Current.Web.UICulture is not affected by the user selected language.



