Koen’s Weblog

SharePoint developer with a life!

Archive for the ‘SharePoint’ Category

Installing SharePoint 2010 – Beta (“Hidden” Prerequisites)

Posted by koenvosters on November 17, 2009

Edit : This is for Windows Server 2008 / you will not be able to install SharePoint 2010 on R2 until in a few days(see comments): http://blogs.msdn.com/opal/archive/2009/11/16/installation-notice-for-sharepoint-2010-public-beta.aspx

The installation of SharePoint 2010 on a new server did take me quite some time to complete. Apart from the prerequisites that are automatically downloaded there are a few other things that you need to download to make it work. This is on a fresh machine, as I’m sure that all your production machines are 100% up to date ;-) Start these downloads before you start your SharePoint install, as the requested hotfix downloads are rather slow.

First of all, after the prerequisites have been installed you get another error message talking about another required hotfix. You can find it on Microsoft Connect. Don’t take the x86 version as that one won’t work, SharePoint 2010 requires 64bit.

Hotfix for token authentication without transport security or message encryption
https://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=21953&wa=wsignin1.0

After that, SharePoint should be installing nicely, up until you run the configuration wizard where SharePoint complains about the version of SQL Server 2008. To get that sorted, download the following patches.

If you are unsure of what version of SQL you got, open a query window and add the following query:

SELECT SERVERPROPERTY(‘ProductVersion’)

SQL Server 2008 Required Patches

Service Pack 1 for SQL Server 2008
http://www.microsoft.com/downloads/details.aspx?familyid=66AB3DBB-BF3E-4F46-9559-CCC6A4F9DC19&displaylang=en
Cumulative Update Package 1 for SQL Server 2008 SP1
http://support.microsoft.com/kb/969099
Request Hotfix Link: http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=969099&kbln=en-us
Cumulative Update Package 2 for SQL Server 2008 SP1
http://support.microsoft.com/kb/970315
Request Hotfix Link: http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=970315&kbln=en-us

This should take you through the configuration wizard as well, after which you can checkout your BRAND NEW SHAREPOINT 2010 Admin Site :)

Posted in SharePoint | Tagged: , | Leave a Comment »

HOWTO : Create a Site with a custom template through code and assign specific user security (User has no rights to create a site).

Posted by koenvosters on September 7, 2009

Imagine the following scenario. In your site collections visitors need to be able to create 1 type of sites. When they create that type of site (with a custom template) they need to become the administrator of that site, as well as the people maintaining the site collection.

How do we do that in SharePoint? We create a site while running with Elevated Privileges, let it inherit the rights of the Site Collection. Once the site is created, we break the inheritance and add specific user rights for that user.

First of all we will be creating a function that accepts a few strings that we need to create the site.

Code Snippet
  1. public string CreateSite(string parentSiteUrl, string siteUrlRequested, string siteTitle, string siteTemplateName)
  2.         {
  3.             return “”;
  4.         }

The parentSiteUrl is the url in which we will be creating the site, the requested siteUrlRequested is the url we will be creating the site in, the siteTitle is the title we will be giving to the site, and the siteTemplateName is the name of the Custom Template we will be using.

Ok, let’s write the code to create our site in our parentsite. In the GetCustomWebTemplates functions we will be getting the custom web template list corresponding the language of the site. In that list we take the template as specified in the parameter of our function (siteTemplateName). As we can’t be sure that the user has checked if a site url already exists we increase a counter till we find a free siteUrl (this is not mandatory, you can also raise an error on the Exists boolean).

Code Snippet
  1. string siteUrlValid = “”;
  2.                 const Int32 localeIdEnglish = 1043;
  3.                 SPSecurity.RunWithElevatedPrivileges(delegate
  4.                                                          {
  5.                     
  6.                     using (SPSite siteCollection = new SPSite(parentSiteUrl))
  7.                     {
  8.                         using (SPWeb parentWeb = siteCollection.OpenWeb())
  9.                         {
  10.                             SPWebTemplateCollection templates = siteCollection.GetCustomWebTemplates(Convert.ToUInt32(localeIdEnglish));
  11.                             SPWebTemplate siteTemplate = templates[siteTemplateName];
  12.                             int counter = 1;
  13.                             siteUrlValid = siteUrlRequested + “_” + counter;
  14.                             while (parentWeb.Webs[siteUrlValid].Exists)
  15.                             {
  16.                                 counter++;
  17.                                 siteUrlValid = siteUrlRequested + “_” + counter;
  18.                             }
  19.                             parentWeb.AllowUnsafeUpdates = true;
  20.                             using (SPWeb myWeb = parentWeb.Webs.Add(
  21.                                 siteUrlValid,
  22.                                 siteTitle,
  23.                                 siteTitle,
  24.                                 Convert.ToUInt32(localeIdEnglish),
  25.                                 siteTemplate,
  26.                                 false, false))
  27.                             {
  28.                                 
  29.                             }
  30.                             parentWeb.AllowUnsafeUpdates = false;
  31.                         }
  32.                     }
  33.                 });
  34.                 return siteUrlValid;

 

With this code our site will be created by making use of the custom template. We are running with Elevated Privileges as the user does not have any permissions to create a subsite. In the using statement of myWeb we will be adding the security changes.

Code Snippet
  1. using (SPWeb myWeb = parentWeb.Webs.Add(
  2.                                 siteUrlValid,
  3.                                 siteTitle,
  4.                                 siteTitle,
  5.                                 Convert.ToUInt32(localeIdEnglish),
  6.                                 siteTemplate,
  7.                                 false, false))
  8.                             {
  9.                                 myWeb.BreakRoleInheritance(true);
  10.                                 SPUser user = myWeb.EnsureUser(SPContext.Current.Web.CurrentUser.LoginName);
  11.                                 SPRoleDefinition def = new SPRoleDefinition(myWeb.RoleDefinitions.GetByType(SPRoleType.Contributor));
  12.                                 SPRoleAssignment assignment = new SPRoleAssignment(user.LoginName, user.Email, user.Name,
  13.                                                                                    user.Notes);
  14.                                 assignment.RoleDefinitionBindings.Add(myWeb.RoleDefinitions[def.Name]);
  15.                                 myWeb.AllowUnsafeUpdates = true;
  16.                                 myWeb.RoleAssignments.Add(assignment);
  17.                                 myWeb.Update();
  18.                                 myWeb.AllowUnsafeUpdates = false;
  19.                                 
  20.                             }

 

With BreakRoleInheritance we break the inheritance of the rules. We do this to be able to add the user to the security of that specific site. We are breaking the security afterwards because we want to make sure that the existing security on the site is copied as well. With the EnsureUser statement we make sure the user exists in that site. The SPRoleDefinition isn’t necessary, but I’m using it to make sure that my code runs on multilingual systems. You could use:

Code Snippet
  1.                                 assignment.RoleDefinitionBindings.Add(myWeb.RoleDefinitions["Contributor"]);

but in a multilingual environment that RoleDefinition isn’t called Contributor. That’s why I will first create a SPRoleDefinition object to make sure that whatever Contributor is called will return the correct name in my SPRoleAssignment. I add the roledefinition to the assignment and then I add the user/role link to the site. Once you have implemented all this your code should look like this:

Code Snippet
  1. public string CreateSite(string parentSiteUrl, string siteUrlRequested, string siteTitle, string siteTemplateName)
  2.         {
  3.             if (siteUrlRequested == null) throw new ArgumentNullException(“siteUrlRequested”);
  4.             try
  5.             {
  6.                 bool returnCondition = false;
  7.                 string siteUrlValid = “”;
  8.                 const Int32 localeIdEnglish = 1043;
  9.                 SPSecurity.RunWithElevatedPrivileges(delegate
  10.                                                          {
  11.                     int counter = 1;
  12.                     using (SPSite siteCollection = new SPSite(parentSiteUrl))
  13.                     {
  14.                         using (SPWeb parentWeb = siteCollection.OpenWeb())
  15.                         {
  16.                             SPWebTemplateCollection templates = siteCollection.GetCustomWebTemplates(Convert.ToUInt32(localeIdEnglish));
  17.                             SPWebTemplate siteTemplate = templates[siteTemplateName];
  18.                             siteUrlValid = siteUrlRequested + “_” + counter;
  19.                             while (parentWeb.Webs[siteUrlValid].Exists)
  20.                             {
  21.                                 counter++;
  22.                                 siteUrlValid = siteUrlRequested + “_” + counter;
  23.                             }
  24.                             parentWeb.AllowUnsafeUpdates = true;
  25.                             using (SPWeb myWeb = parentWeb.Webs.Add(
  26.                                 siteUrlValid,
  27.                                 siteTitle,
  28.                                 siteTitle,
  29.                                 Convert.ToUInt32(localeIdEnglish),
  30.                                 siteTemplate,
  31.                                 false, false))
  32.                             {
  33.                                 myWeb.BreakRoleInheritance(true);
  34.                                 SPUser user = myWeb.EnsureUser(SPContext.Current.Web.CurrentUser.LoginName);
  35.                                 SPRoleDefinition def = new SPRoleDefinition(myWeb.RoleDefinitions.GetByType(SPRoleType.Contributor));
  36.                                 SPRoleAssignment assignment = new SPRoleAssignment(user.LoginName, user.Email, user.Name,
  37.                                                                                    user.Notes);
  38.                                 assignment.RoleDefinitionBindings.Add(myWeb.RoleDefinitions[def.Name]);
  39.                                 myWeb.AllowUnsafeUpdates = true;
  40.                                 myWeb.RoleAssignments.Add(assignment);
  41.                                 myWeb.Update();
  42.                                 myWeb.AllowUnsafeUpdates = false;
  43.                             }
  44.                             returnCondition = true;
  45.                             parentWeb.AllowUnsafeUpdates = false;
  46.                         }
  47.                     }
  48.                 });
  49.                 if (!returnCondition)
  50.                 {
  51.                     siteUrlValid = “”;
  52.                 }
  53.                 return siteUrlValid;
  54.             }
  55.             catch (Exception)
  56.             {
  57.                 return null;
  58.             }
  59.         }

Calling the function can be done like this (Web is the SPContext.Current.Web object).

Code Snippet
  1. siteUrl = CreateSite(Web.Url, siteUrl, siteTitle, “tbtemplate.stp”);

Posted in Development, SharePoint, SharePoint 2007 | Tagged: , , , | 2 Comments »

Unable to copy VM Harddrives to external disk – FAT 32

Posted by koenvosters on September 3, 2009

As from time to time I buy a new disk to store my old VM’s on at the first copy I get an error message when I try to copy hard disk of my vm to my external disk. That’s due to the fact that those disks are mainly formatted as FAT32 (which can handle 4 GB). As I wanted to put a vhd on my work backup disk I got the same message, and I did not want to delete the backups I already took I looked for a command to change it without having to format the drive, and I found it :)

convert <drive> /fs:ntfs works. You should execute it in a command window that you are running as an administrator.

Posted in SharePoint, SharePoint 2007 | Leave a Comment »

HOWTO : Get the Last ItemID in a list

Posted by koenvosters on August 20, 2009

The following code shows you how to get the last item of an ID in a list. Warning, this code gets you the last item from that list meaning that if you use this code to get the last item you added, it will go wrong if someone adds an item between you adding it and executing this query. In that case I advise you to get a unique identifier that you add to each item and get the item by that id.

Code Snippet
  1. const string siteurl = “http://sitecollection”;
  2.             using (var site = new SPSite(siteurl))
  3.             {
  4.                 using (var web = site.OpenWeb(“myweb”))
  5.                 {
  6.                     var list = web.Lists["mylist"];
  7.                     var query = new SPQuery
  8.                                     {
  9.                                         Query = “   <OrderBy> <FieldRef Name=’ID’ Ascending=’False’ /> </OrderBy>”
  10.                                     };
  11.                     var items = list.GetItems(query);
  12.                     SPListItem item;
  13.                     if (items.Count > 0)
  14.                         item = items[0];
  15.                 }
  16.             \

Posted in Development, SharePoint, SharePoint 2007 | Tagged: , , | Leave a Comment »

Your client does not support opening this list with Windows Explorer

Posted by koenvosters on August 17, 2009

Your client does not support opening this list with Windows Explorer is an error I see popping up a lot of times. What can you do to fix it?

If you are using IE6:
http://support.microsoft.com/kb/325355/

If you are using IE7 OR IE8
Vista, Windows Server 2003, XP : http://www.microsoft.com/downloads/details.aspx?FamilyId=17C36612-632E-4C04-9382-987622ED1D64&displaylang=en

Posted in SharePoint, SharePoint 2007 | Tagged: , | Leave a Comment »

HOWTO : Getting the User Properties from Active Directory with People Picker

Posted by koenvosters on August 10, 2009

A while ago I had to get additional properties from Active Directory. It was important that the information was live (I could not consider the information that got imported by the User Profile Import to be 100% up-to-date. To get this done I wrote this little piece of code (don’t forget to reference System.DirectoryServices):

private ResultPropertyCollection GetUserProperties(string userAccount)

    {

        DirectoryEntry entry = new DirectoryEntry();

        entry.Path = "LDAP://CUSTOMER";

        entry.AuthenticationType = AuthenticationTypes.Secure;

        //DirectorySearcher _searcher = new DirectorySearcher(entry);

 

        String account = userAccount.Replace(@"CUSTOMER\", "");

        try

        {

            using(HostingEnvironment.Impersonate())

            {

                        DirectorySearcher search = new DirectorySearcher(entry);

                        search.Filter = "(SAMAccountName=" + account + ")";

                        search.PropertiesToLoad.Add("department");

                        search.PropertiesToLoad.Add("mail");

                         search.PropertiesToLoad.Add("title");

                        search.PropertiesToLoad.Add("company");

                        SearchResult result = search.FindOne();

                       

                        if (result != null)

                        {

                            return result.Properties;

                        }

                        else

                        {

                            return null;

                        }

            }

        }

        catch (Exception ex)

        {

            lblResult.Text = ex.Message;

            return null;

        }

    }

Replace CUSTOMER with your DOMAIN.
I added one more function to easily get a property out of the collection:

private string GetFromUserProperties(ResultPropertyCollection _properties, string _prop)

    {

        try

        {

            if (_properties[_prop].Count > 0)

            {

                return _properties[_prop][0].ToString();

            }

            else

            {

                return "";

            }

        }catch(Exception ex){

            return "";

        }

    }

When you select a user in a People Picker it calls a postback. In the Onload event of your page handle the call of the following function

private void CheckAndFillInfo(SPWeb site)

    {

       

        if (spPELeidinggevende.ResolvedEntities.Count > 0)

        {

            PickerEntity _pe = (PickerEntity)spPELeidinggevende.ResolvedEntities[0];

            SPUser _spuser = site.EnsureUser(_pe.Key);

 

               

                ResultPropertyCollection _results = GetUserProperties(_spuser.LoginName);

                if (_results != null)

                {

                   

                    txtFunction.Text = GetFromUserProperties(_results, "title");

                }

        }

        else

        {

            txtFunction.Text = “”;

        }

    }

That should do the trick.

Posted in Development, SharePoint, SharePoint 2007 | Tagged: , | Leave a Comment »

Putting workflow code in a separate project (using wspbuilder)

Posted by koenvosters on August 7, 2009

As I am rebuilding one of our projects to make it easier to deploy I had to put the workflow code in one separate project. As I thought this would be a piece of cake I didn’t expect Visual Studio to show me a bunch of errors when doing so. The one that kept appearing was "The service ‘System.Workflow.ComponentModel.Compiler.ITypeProvider’ must be installed for this operation to succeed. Ensure that this service is available". After looking it up I got a bunch of different guids that I could put in my project file, but none of them seemed to do the trick. Until I checked out a WPF workflow post that told me to use some other guids and they worked fine. So, how do we start.

First of all, we will be creating a project that is called MyCustomer.MySuperSolution. We will make it a WSP Project or a class library. We will add a new item, which will be a blank feature (WSPBuilder Item). Secondly, we will be creating another WSP Project or class Library and call it MyCustomer.MySuperSolution.Workflows. We will be adding a sequential workflow feature that project. Let’s call it EmailWorkflow. As this will create it’s own solution (and that is not what we want, we want 1 wsp for the whole project) we will be making some changes. First of all, rename the feature folder that is called EmailWorkflow to MyCustomer.MySuperSolution.EmailWorkflow. That way it will have a decent naming convention in the feature folder. Move that folder to the same location in your MyCustomer.MySuperSolution project. Then delete the complete 12 folder structure from your MyCustomer.MySuperSolution.Workflows project. You can also remove the solutionid.txt file as it is no longer needed. Do not remove the snk as your assembly needs to be strong named.

Two steps remain, which are making sure that when you recompile your workflow solution that it is added to the manifest.xml by wspbuilder when you select build wsp, and to remove the dreadful errors in your workflow project. To make sure the assembly is added, right-click on your project, properties, build, output path. Point the output path to the bin/debug folder of your MyCustomer.MySuperSolution project. It is a good idea to also do that for the release configuration as many times you forget to set that up while building for release (which is then the bin/Release folder). To remove the dreadful ITypeProvider errors you need to open your project with notepad. Change your ProjectTypeGuids to:

<ProjectTypeGuids>{14822709-B5A1-4724-98CA-57A101D1B079};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

and add the following line near the end of the file (there is already one import statement)

<Import Project="$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.0\Workflow.Targets" />

If you want to target the WF of .Net Framework 3.5 just change 3.0 to 3.5

Posted in Development, SharePoint, SharePoint 2007 | Tagged: , , , | Leave a Comment »

Real World Branding in SharePoint on MSDN

Posted by koenvosters on August 7, 2009

There is a very nice article on MSDN, published by Andrew Connell and Randy Drisgill explaining you how to customize SharePoint and give it a very sexy look. Definetely a must read.

http://msdn.microsoft.com/en-us/library/ee354191.aspx

Posted in Development, SharePoint, SharePoint 2007 | Leave a Comment »

Showing the real error message in SharePoint

Posted by koenvosters on August 6, 2009

It seems like a lot of those questions still are popping up on forums, even though Bing & Google bring you right to it. Instead of pointing those people to other blogs, I might as well point them to this nice blog :)

There are two settings in your web.config you need to change to enable custom errors. This web.config is located in c:\inetpub\wwwroot\VirtualDirectories. In that folder you have 2 possible foldernames: foldernames with a number and foldernames with a name. If you are using hostnames then the web.config file you are looking for is containt in the <hostname> folder. If you are not using hostnames, the name of the folder corresponds to the port your web application is running on.

Open the web.config and look for the CallStack=”false” attribute. Put it to true.
Then search for the CustomErrors=”on” tag and change it to off.

Once those two actions are done you will see a more detailed error message.

Posted in Development, SharePoint, SharePoint 2007 | Leave a Comment »

SharePoint : stop firing events while I run my code

Posted by koenvosters on August 2, 2009

Ok, this small post to keep coverning events:

How do I stop events from firing in my code?

this.DisableEventFiring(); 

And how do I put it back on?

this.EnableEventFiring();

Posted in 2010, Development, SharePoint, SharePoint 2007 | Leave a Comment »