I recently had to deploy a site template that was built using SharePoint Enterprise Edition 2007 on an instance of SharePoint Standard Edition 2007.
Obviously given that some features were not available in the Standard Edition I received the ‘The template you have chosen is invalid or cannot be found’. Unlike a MOSS to WSS conversion the problem here is that the features do exist on the server but are simply not available for the standard edition.
I basically resorted to manually comparing the differences between a site template created in the Standard edition vs one created in the Enterprise edition.
Here’s the list if anyone ever needs this.

Remove these features from a template created in the Enterprise edition if you want to deploy it on a Standard edition. Obviously you need to test to ensure that your template is not actually using any of the Enterprise features.
<Feature ID="065c78be-5231-477e-a972-14177cc5b3c7" />
<Feature ID="0806d127-06e6-447a-980e-2e90b03101b8" />
<Feature ID="2510d73f-7109-4ccc-8a1c-314894deeb3a" />
<Feature ID="e8734bb6-be8e-48a1-b036-5a40ff0b8a81" />
<Feature ID="00bfea71-dbd7-4f72-b8cb-da7ac0440130" />
This had me tripped for a while. I was bulk inserting items (~800) to a list which had event receivers as well as a workflow attached.
The problem was that the workflow was not being triggered. Or if it did it just hung at In Progress.
After poking around for more than an hour I discovered that if I inserted a single item it worked. So to fix the issue I added a ten second sleep (Thread.Sleep) between the inserts and the workflows are triggering away happily.
On the project I am currently working on I had to implement a custom business rule for a list. The requirement was that only users in an Administrator group should be allowed to edit a particular field. All other users can edit that list but they are not allowed to touch that particular field.
Given that this was the first time I had to do this in SharePoint I did some research to figure out the best practice but came up empty. Most of suggestions were to customize the edit form and add the logic there. This clearly will not work since the business rule validation is in the UI and not in the actual list. Hence leaving it open for anyone to open in datasheet view or any of the other numerous ways (e.g. web services) to break the business rule.
[Note: While researching for this post I did come across the ‘Enforcing Custom List Item Data Validation’ best practice by SharePoint patterns and practices group, which essentially makes the same recommendation as this blog post.]
SharePoint 2010 makes it a little easy with the Validation Formula feature which lets you add business rules to any list directly from the UI. But with SharePoint 2007 you’ll need to use an SPItemEventReceiver to implement your business rule.
There is a good code sample on validating a list in the List Item Event Receivers article on TechNet.
In my very first webpart that I wrote I needed to write some CAML queries to filter and sort the lists.
Being the type of guy who hates seeing strings littering my code I searched the net for an API for CAML queries. Thankfully John Holliday had already done the hard work and created CAML.NET. Check out the clean syntax for the CAML code.
1: string typeName = "My Content Type";
2: string simpleQuery =
3: CAML.Query(
4: CAML.Where(
5: CAML.Or(
6: CAML.Eq(
7: CAML.FieldRef("ContentType"),
8: CAML.Value(typeName)),
9: CAML.IsNotNull(
10: CAML.FieldRef("Description")))),
11: CAML.GroupBy(
12: true,
13: CAML.FieldRef("Title",CAML.SortType.Descending)),
14: CAML.OrderBy(
15: CAML.FieldRef("_Author"),
16: CAML.FieldRef("AuthoringDate"),
17: CAML.FieldRef("AssignedTo",CAML.SortType.Ascending))
18: );
Here again you might run into the issue of adding an extra assembly to your deployment, the simple alternative that I took was to include the CAML class directly into me source tree. But remember to keep the copyright and license header in place as stated by the Ms-CL license.
Hopefully Microsoft will release a Linq to CAML library soon, there is already one at CodePlex by a Microsoft employee but what would be better is if it comes with SharePoint.
The documentation for the ModifyUserPropertyByAccountName method of the UserProfileService in the SharePoint Server SDK has a bug.
You’ll notice that although there are no errors reported the profile doesn’t get updated. The fix is quite simple though and is actually present in the other examples. Setting the IsValueChanged to true does the trick.
Here’s how the corrected code looks like.
1: namespace ModifyUserPropertyByNameSample
2: {
3: class Program
4: {
5:
6: static void Main(string[] args)
7: {
8: //Instantiate the Web service.
9: UserProfileService userProfileService =
10: new UserProfileService();
11:
12: //Set credentials for requests.
13: //Use the current user log-on credentials.
14: userProfileService.Credentials =
15: System.Net.CredentialCache.DefaultCredentials;
16:
17: PropertyData[] newdata = new PropertyData[1];
18: newdata[0] = new PropertyData();
19:
20: newdata[0].Name = "FirstName";
21: newData[0].IsValueChanged = true;
22:
23: newdata[0].Values = new ValueData[1];
24: newdata[0].Values[0] = new ValueData();
25: newdata[0].Values[0].Value = "Mark";
26:
27: // TODO
28: // Replace "domain\\username" with valid values.
29: userProfileService.ModifyUserPropertyByAccountName
30: ("domain\\username", newdata);
31:
32: }
33: }
34: }
For what it’s worth I’ve uploaded a working solution to the MSDN Code Gallery that allows you to view the current profile data and make changes by providing the name/value pair through the query string. You can download the SharePoint Profile Updater here.
If you want to delete or remove all the items in a SharePoint list you need to iterate through each item and perform a delete. Most of the examples on the web iterate through each item to do the delete. The problem there is that each delete action makes a request to the server and a huge list is going to take a long time. You could always delete the entire list and recreate it but that would mean recreating the structure as well as the guid being changed.
The better method would be to make a single request with all the delete commands batched together as shown in the code sample below.
1: private static StringBuilder BuildBatchDeleteCommand(SPList spList)
2: {
3: StringBuilder sbDelete = new StringBuilder();
4: sbDelete.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch>");
5: string command = "<Method><SetList Scope=\"Request\">" + spList.ID +
6: "</SetList><SetVar Name=\"ID\">{0}</SetVar><SetVar Name=\"Cmd\">Delete</SetVar></Method>";
7:
8: foreach (SPListItem item in spList.Items)
9: {
10: sbDelete.Append(string.Format(command, item.ID.ToString()));
11: }
12: sbDelete.Append("</Batch>");
13: return sbDelete;
14: }
I’ve published a working solution on the MSDN Code Gallery at http://code.msdn.microsoft.com/SharePointListDelete.