Koen’s Weblog

SharePoint developer with a life!

The Web application at (url) could not be found.

Posted by koenvosters on February 1, 2010

Possible causes:

- You made a typo.
- You made a typo.
- You created a SharePoint 2007 x64 development machine. Don’t do that, make a x86 (32bit) installation and forget about developing under x64 for MOSS 2007.
- You are running a website that accesses SharePoint data and the application pool does not have the same identity as the application pool SharePoint is running under. In my opinion this should work with any identity as long as it has acces to SharePoint but clearly it doesn’t… Rules there are supposed to be that the user accessing the SPSite object should be a site collection administrator?

Note that I added you made a typo twice, it’s because for some reason in my environment the create a new web application page added a dot (.) after my servername, so my web application url was http://servername.:2010 instead of http://servername:2010. Internet Explorer works PERFECTLY when you use http://servername:2010 without the dot (.) but when you copy this into your code it gives an error as it is looking for http://servername.:2010. This one got me stuck for quite a while.

Posted in Development, SharePoint | Tagged: , , , | 1 Comment »

One or more field types are not installed properly. Go to the list settings page to delete these fields.

Posted by koenvosters on January 27, 2010

Today one of our developers got this error when using an SPQuery. He asked me to help out, and in most cases it means that you are not using the internal name of the field. So that was the first step I took to replace his code and use the internal name of the field. The best way of course would be to use the internal field as a parameter:

q.Query = string.Format(“<Where>” +

“<And>” +

“<Eq>” +

“<FieldRef Name=\”{0}\”></FieldRef><Value Type=\”Boolean\”>1</Value></Eq>” +

“<Eq><FieldRef Name=\”{1}\”></FieldRef><Value Type=\”Boolean\”>1</Value>” +

“</Eq>” +

“</And>” +

“</Where>”, spField1.InternalName, spfield2.InternalName);

After doing that, it still gave the same error. Debugging it showed us that the same error kept popping up, although the internal field names were used. Last resort was to use the U2U CAML Query builder and see if anything was wrong. It appeared that the </Eq><Eq> was missing between the FieldRefs. This is what the correct query string should be:

q.Query = string.Format(“<Where>” +

“<And>” +

“<Eq>” +

“<FieldRef Name=\”{0}\”></FieldRef><Value Type=\”Boolean\”>1</Value></Eq>” +

“<Eq><FieldRef Name=\”{1}\”></FieldRef><Value Type=\”Boolean\”>1</Value>” +

“</Eq>” +

“</And>” +

“</Where>”, spField1.InternalName, spfield2.InternalName);

So even though the error message usually means that your internal names are not correct, messing up the query with the <Eq> tags seems to result in the same error.

Posted in Development, SharePoint | Leave a Comment »

SharePoint 2010 install error : The errorData argument cannot be null or zero length

Posted by koenvosters on January 26, 2010

I know it’s been a while, but going through some heavy personal stuff isn’t really productive late at night, so I took the time to do some other stuff then spending time in front of my pc at night and work out stuff in SharePoint 2010. But as always there’s a time where you pull it all together again, and that time is now.
When I started to install a new clean SharePoint 2010 server I came across this error during the configuration wizard (when selecting the SQL Server instance):

System.ArgumentNullException was thrown. Additional exception information: The errorData argument cannot be null or zero length. Parameter name: errorData.

Googling/Binging it brought me to various solutions about firewalls etcetera, but as this was a local machine install that couldn’t be the cause of the problem. Appearantly this cryptic message just means one thing: I can’t find your SQL Server. Due to changing the development machine to a domain controller after installing SQL, the service account for SQL didn’t have the required access. If you have the same problem, do not change it in your services screen, change it in your SQL Server Configuration Manager. If that fails with an error message (as it did in my case), add the service account to your administrator group, start the services, fake to change it again and remove the account from the administrator group. That should leave you with a running SQL and now you can run the configuration wizard of SharePoint 2010.

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

I found my theme back!

Posted by koenvosters on December 16, 2009

Yep, after spending some time in the theme selector I found my theme back. I changed it to a nice red for the christmas period.
Today is gonna be a good day :p On a sidenote, I’m looking into MVC and learning some cool stuff, soon back to SharePoint 2010 though :)

Posted in Personal | Tagged: , | 2 Comments »

ERROR: Failed invoking job id

Posted by koenvosters on December 14, 2009

Today my development machine decided to crash and burn down. SharePoint Central admin was no longer working. When that no longer works, step one is to start the configuration wizard and hope it fixes everything. But that failed as well. It did however gave me an exception that helped me figure out what was going wrong: An exception of type System.Security.Principal.IdentityNotMappedException was thrown. Additional exception information: Some or all identity references could not be translated.
In my SharePoint logs I had the following error popping up constantly:

12/14/2009 13:50:01.32 OWSTIMER.EXE (0×0160) 0×0168 Windows SharePoint Services Timer 5uuq Unexpected ERROR: Failed invoking job id {A71C27B4-9023-4727-A90B-3E60171CF790}
12/14/2009 13:50:04.31 OWSTIMER.EXE (0×0160) 0×00DC Windows SharePoint Services General 8e2s Medium Unknown SPRequest error occurred. More information: 0×80070005

So something was wrong with the identities. As it is a development box and no one else touches it but me I knew none of the identies/passwords were changed. I have no clue how it went wrong, but by making use of stsadm -o updatefarmcredentials -userlong -password I managed to get everything up and running again.

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

BIWUG – SharePoint 2010 – 17 december 2009

Posted by koenvosters on December 10, 2009

The BIWUG Team (Belgian Information Worker User Group) is organising some new sessions on SharePoint 2010. The first session is taking place on 17 december 2009 at the buildings of Ordina in Mechelen.
Agenda:

18:00 – 18:30: Welcome

18:30 – 19:00: Introduction to SharePoint Server 2010 (Karine Bosch – SharePoint MVP)
19:00 – 19:30: LINQ to SharePoint (Stephane Eyskens – SharePoint MVP)
19:30 – 20:00: Client Object Model (Jan Tielens – SharePoint MVP)

20:00 – 20:15: Break

20:15 – 20:45: Business Connectivity Services (Frank Cleynen)
20:45 – 21:15: Workflow (Peter Plessers)

See you there!

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

Scott Guthrie in Belgium

Posted by koenvosters on December 7, 2009

Normally I don’t blog about events, but this one was especially nice as, for those who don’t know it, ScottGu always presents in a red polo. As an original addition the people organizing the event had everyone in the audience wear a red polo as well. This resulted in some great pictures:
ScottGu in Belgium

What did he talk about?

  • Visual Studio 2010
  • .net Development
  • asp.net Development
  • Silverlight 4.0
  • MVC 2.0

The material of his slides can be found in Scott’s blog post:

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

New Layout

Posted by koenvosters on December 1, 2009

Well, here is a new layout. Not because I got tired of the old one, but because I was playing around with the new themes and accidentally applied it. No worries, I can change it back to the old one. Where is the old one? It’s gone! So this one until I figure out how to get the old one back.

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

Updating / Upgrading SharePoint Server 2007

Posted by koenvosters on December 1, 2009

As I accidentally deleted my SharePoint Server 2007 patches folder I had to go look for them on the web. It’s easy enough to remember that there is an SP1 and and SP2, but what were all those cumulative updates again? It took me quite a while to figure out where you could get a list of all the updates available for SharePoint Server 2007 after the SP1 hotfix, apart from the obvious being SP2. After quite some searching I found this nice Technet page that both has a link to the updates and tells you in which ones and in which order you should install them. Have fun patching!
http://technet.microsoft.com/en-us/library/cc263467.aspx

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

SharePoint 2010 : White Page when clicking buttons on the ribbon.

Posted by koenvosters on November 17, 2009

If you are getting white pages when clicking on buttons on the Ribbons you should add your SharePoint 2010 site to your trusted sites. It has to do with certain javascript functions that cannot be called which gives that effect (happens mostly if you are testing it on a server)

Posted in Ribbon | Tagged: | Leave a Comment »

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 »

Enabling Virtualization on your Sony Vaio

Posted by koenvosters on November 9, 2009

This weekend I bought myself a Sony Vaio to be able to run SP2010 on a laptop as well (so that when I got some time during noon I can play around). After installing Windows Server 2008 R2 on it and enabling Hyper-V I got this nice message telling me that virtualization on a Sony Vaio is disabled. After checking online I found only links to obscure BIOS hacks to enable this, and a blog post of one of the big guys of Sony telling us that in the future it would be enabled. That blog post was 4 months ago but my stuff wasn’t working and brand new. Luckily, the Sony site has a BIOS update utility to enable this, but search engines didn’t turn up anything about it, therefor this post. Select the model of your VAIO, select downloads and then the BIOS Utility. Take into account that installing the BIOS update does not enable your hardware virtualization. You need to press F2 to get into your BIOS, enable hardware virtualization and you are ready to go. The machine rocks btw, and for a price of 1260 euro it’s pretty high on the value/quality part as far as I’m concerned as it has 6GB of memory.

Posted in 2010, Hardware | Tagged: , , | Leave a Comment »

HOWTO: Add a button to the ribbon in SharePoint 2010

Posted by koenvosters on November 5, 2009

This post is intended for BETA1. It will work on BETA2 as well, just remove the … for

After a few hours of messing around in XML, we (Jopx and I) figured out how to put a button on the Ribbon. First of all, how does it work? There is some XML (located in the 14 hive/templates/global/xml) in a file called CMDGui.XML. This contains the entire Ribbon XML that is used to render the ribbon. To get that XML into a Ribbon, there are two javascript files that translate that data into a workeable ribbon (CUI.js and SP.Ribbon.js). What do we need to do to create our custom button? It’s quite simple, you just create some XML, push it to the SharePoint environment by making use of an empty element, add some stuff to the templates/xml folder and you’re set. That is once you figured it all out :)

First of all, create a new Empty SharePoint project in Visual Studio. (no screenshots after this as my laptop here can’t run SP2010)

image

  • Rename your project to MyCoolButton
  • Add an empty Element.
  • In that element, paste the following xml:
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction Id="MeSoCool" Location="CommandUI.Ribbon.Documents.New.Controls._children">
    <CommandUIExtension>
      <CommandUIDefinitions>
        <CommandUIDefinition Location="CommandUI.Ribbon.Documents.New.Controls._children">
          <Button Id="Ribbon.Documents.New.Controls.MyCoolButton"
                  Image16by16="/_layouts/images/edit.gif"
                  Image32by32="/_layouts/images/placeholder32x32.png"
                  Description="MyDescription"
                  Command="MyCoolButton"
                  LabelText="Banzai"
                  Sequence="60"
                  TemplateAlias="o1" />
        </CommandUIDefinition>
      </CommandUIDefinitions>
    </CommandUIExtension>
  </CustomAction>
</Elements>

What does all this XML mean?

First of all we will be adding a CustomAction, and the most important attribute there is the Location. This location attribute will define where the button is going to appear. Notice that the same attribute is also defined in the CustomUIDefinition which is the location where it will need to be defined in Beta2. So in Beta1 apply the Location to the CustomAction, in Beta2 only apply the location to the CommandUIDefinition. Notice the _children in the end, you need to add it to be able to add buttons to that Control collection.

Where does this location come from? In the CMDGui.XML file that location is defined in a group. This group is part of a group collection called Ribbon.Documents.Groups which is part of the Tab called Ribbon.Documents.  This tab is the ribbon we will see when we are working with documents. Important to notice is the Template the group is using. If the Template used is Ribbon.Templates.Flexible2 you can add buttons to that group. If it isn’t a flexible template (like Ribbon.Templates.ThreeRowsSixAlignedControls2) then you can’t add buttons as those are fixed templates. As an example I added the xml for the Ribbon.Documents.New group.

<Group
            Id="Ribbon.Documents.New"
            Sequence="10"
            Command="DocumentNewGroup"
            Description=""
            Title="$Resources:core,cui_GrpNew;"
            Image32by32Popup="/_layouts/images/placeholder32x32.png"
            Template="Ribbon.Templates.Flexible2"
          >

 

Ok, on to the next item in our XML, the CommandUIExtensions. They contain the CommandUIDefinitions who are defining the element that you are showing (a Button in our case). The name of the second element escapes me and I can’t check SP2010 at the moment, but the other element within the CommandUIExtensions defines the action of the button (what happens if you click on it) Our little post is only focused on making it appear. Now back to our Button Control.

<Button Id="Ribbon.Documents.New.Controls.MyCoolButton
             Image16by16="/_layouts/images/edit.gif"

             Image32by32="/_layouts/images/placeholder32×32.png"

             Description="MyDescription"

             Command="MyCoolButton"

             LabelText="Banzai"

             Sequence="60"

            TemplateAlias="o1" />

The Id needs to start with Ribbon.Documents.New.Controls. After that you can put whatever you want. The image attributes are used and the images are shown depending on what is defined in the GroupTemplates. What does that mean? In the GroupTemplates (also defined in the CMDGui.xml) it is defined how a button in the ribbon should behave when the page gets resized. Should it hide itself, should it change it’s template (for instance instead of 3 large buttons next to eachother 3 small buttons above eachother)That way we can control how our Ribbon is behaving when the page gets resized. Description is quite easy to understand what it does, Command links to the command that you can define afterwards (you can deploy without having implemented the command), the LabelText is used in the template and shown on the ribbon, the Sequence defines where the button needs to be places and the TemplateAlias links to the template that you are using for that button.

Ok, now that we have that XML we just need to do one more thing:

Add a SharePoint mapped folder to your project and link it to the templates/xml folder. It should automatically create a MyCoolButton folder under the XML folder, but if it doesn’t make sure you do. Add an xml file to it callee MyCoolButton.xml. In that file we will define our link to the javascript files.

<script OnDemandKey="ribbon">
  <File></File>
  <File>SP.Ribbon.js</File>
</script>


Now we are set to go. Rightclick your project, select deploy. Go to a document library, on the ribbon select Documents and you should see a new button next to the New Folder button. (More images will follow as soon as I get home, but we were so excited when it finally worked that I at least had to put it online, but I’m sure Joris will do the same very soon :) )

Should I have missed something, let me know, but this should do the trick for you :)

Posted in 2010, Development, Ribbon | Tagged: | 2 Comments »

Using Javascript and jQuery in MOSS

Posted by koenvosters on October 15, 2009

Jan Tielens released a very nice solution to allow you to easily integrate Javascript and jQuery in your SharePoint sites without having to go through several configurations steps. It allows you to just upload your javascript files to a document library and they will be available in your SharePoint pages. Check it out here.

Posted in Development, 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 | 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 »

HOWTO: Create an Event Handler for SharePoint(MOSS 2007)

Posted by koenvosters on July 31, 2009

As I see this question popping up on many forums, I thought it would be time to write a tutorial about it, even though there are already quite a few of them handling the subject.

Prerequisites:

How-to Create an Event Handler by making use of a feature:

To start with : what exactly is an event handler for SharePoint? It’s a piece of code that is triggered when something (an event!) happens. When that happens, our event handler can replace what is supposed to happen with our own code. How do we build that in Visual Studio (using WSP Builder)?

First of all, we will be creating a WSP Builder Project called MyEventHandler:

image

Once the project is created, we will right-click the project and select add new item. In the left column, select WSPBuilder and select Event Handler in the template list. In the name field I chose to call it DemoEventHandler.

image

You’ll get a new screen where you can define the scope of the feature. You can leave it at Web

image

After this step your project will have three additional files added to it and a few folders:

image

feature.xml: the CAML based declaration of your feature.
elements.xml: the CAML based declaration of the element(s) in your feature, which is your event handler in this case.
DemoEventHandler.cs : the code that will be overriding the existing SharePoint Event Handlers.
Let’s take a look at our feature.xml code:

<?xml version="1.0" encoding="utf-8"?>

<Feature Id="875e92bb-782c-40b4-a5a9-f55423df667e"

   Title="DemoEventHandler"

   Description="Description for DemoEventHandler"

   Version="12.0.0.0"

   Hidden="FALSE"

   Scope="Web"

   DefaultResourceFile="core"

   xmlns="http://schemas.microsoft.com/sharepoint/">

   <ElementManifests>

      <ElementManifest Location="elements.xml"/>

   </ElementManifests>

</Feature>

What this file does is identify the feature for SharePoint (Id), give it a title and description (which will be shown on the feature activation site), define a scope (where Web means site, where Site means Site Collection and then there is Web Application and Farm as possible scopes.
Another important part of the feature is the <ElementManifests> area. That area defines all the items that make part of the feature while the manifests themselves describe that specific part. As it is here the case with the event handler:

<?xml version="1.0" encoding="utf-8" ?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

   <Receivers ListTemplateId="100">

      <Receiver>

         <Name>AddingEventHandler</Name>

         <Type>ItemAdding</Type>

         <SequenceNumber>10000</SequenceNumber>

         <Assembly>MyEventHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ca176e059473d6b1</Assembly>

         <Class>MyEventHandler.DemoEventHandler</Class>

         <Data></Data>

         <Filter></Filter>

      </Receiver>

   </Receivers>

</Elements>

What is important for us? First of all the ListTemplateId. The ListTemplateId defines to which List Types the Event Handler will be targeting. The table here below shows which list types there are available in SharePoint 2007:

ID Name
100 Generic list
101 Document library
102 Survey
103 Links list
104 Announcements list
105 Contacts list
106 Events list
107 Tasks list
108 Discussion board
109 Picture library
110 Data sources
111 Site template gallery
112 User Information list
113 Web Part gallery
114 List template gallery
115 XML Form library
116 Master pages gallery
117 No-Code Workflows
118 Custom Workflow Process
119 Wiki Page library
120 Custom grid for a list
130 Data Connection library
140 Workflow History
150 Gantt Tasks list
200 Meeting Series list
201 Meeting Agenda list
202 Meeting Attendees list
204 Meeting Decisions list
207 Meeting Objectives list
210 Meeting text box
211 Meeting Things To Bring list
212 Meeting Workspace Pages list
300 Portal Sites list
301 Blog Posts list
302 Blog Comments list
303 Blog Categories list
1100 Issue tracking
1200 Administrator tasks list
2002 Personal document library
2003 Private document library

 

Once we have defined which list we are going to target we will define that we are overriding an ItemAdding event. ItemAdding means that the event will be fired right before the item is added to the list. This allows us to modify the item before it is saved to the list. The other parameters aren’t that important at the moment, apart from the Assembly and Class that will be linking to the assembly that contains the code of your event handler.

Possible events that you can override:

ItemAdded
ItemAdding
ItemAttachmentAdded
ItemAttachmentAdding
ItemAttachmentDeleted
ItemAttachmentDeleting
ItemCheckedIn
ItemCheckedOut
ItemCheckingIn
ItemCheckingOut
ItemDeleted
ItemDeleting
ItemFileConverted
ItemFileMoved
ItemFileMoving
ItemUncheckedOut
ItemUncheckingOut
ItemUpdated
ItemUpdating

Ok, so we checked out the feature.xml and the elements.xml, but there is also the DemoEventHandler.cs file. That contains the actual code of our event handler:

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.SharePoint;

 

namespace MyEventHandler

{

    class DemoEventHandler : SPItemEventReceiver

    {

      public override void ItemAdded(SPItemEventProperties properties)

      {

          base.ItemAdded(properties);

      }

 

      public override void ItemAdding(SPItemEventProperties properties)

      {

          base.ItemAdding(properties);

      }

 

      public override void ItemUpdated(SPItemEventProperties properties)

      {

          base.ItemUpdated(properties);

      }

 

      public override void ItemUpdating(SPItemEventProperties properties)

      {

          base.ItemUpdating(properties);

      }

 

    }

}

If you deploy it like this your event handler will run, but it will just call the base class and nothing special will happen. Let’s change the ItemAdding Event (as it is already defined in our CAML to be deployed). We will change the itemadding event so that it will check, when an item is being added, by making sure the CheckValue column does not contain the string “dontadd”. If it does contain dontadd, an error message is displayed and the item is NOT added to the list. To do this, we modify the ItemAdding Event to this:

public override void ItemAdding(SPItemEventProperties properties)

{

    if (properties.AfterProperties["CheckValue"].ToString() == "dontadd")

    {

        properties.ErrorMessage = string.Format("The CheckValue column equals dontadd -> item will not be added.");

        properties.Status = SPEventReceiverStatus.CancelWithError;

        properties.Cancel = true;

    }

}

A little extra explanation. The AfterProperties contain the NEW values of an item. The BeforeProperties contain the OLD values of an item in case of an update. For an ItemAdding event the BeforeProperties are empty. What we do here is check the CheckValue properties value. If it contains “dontadd” we show the error message and by making use of properties.Status = SPEventReceiverStatus.CancelWithError we cancel the base.ItemAdding(properties) call. By adding properties.Cancel = true we cancel the Itemadding event.

Ok, so now we built this, but how do we get this working on our SharePoint site? With WSPBuilder that is quite easy. Rightclick on your project, select WSPBuilder / Build WSP. This will create a solution file to be deployed on your SharePoint farm. Once that is done, select WSPBuilder / Deploy and the solution will be installed and deployed to your farm.

image  

Ok, one thing to note here is that the event handler will be targeting all lists. This means that every list that does not contain the CheckValue column will no longer work. But checking if the column exists is something that you should be able to do yourself. Once it is deployed to your SharePoint farm, create a new Custom List and Add the column CheckValue of type text. Then go to Site Settings, Site Features (NOT Site Collection Features as the scope was Web) and activate our newly deployed feature:

image

Ok, now we can test it by adding a new item with CheckValue equal to dontadd.

image

If you did everything according to plan, this is the information you should be receiving when you click ok:

image

Happy Coding!

In addition I added a few other interesting bits regarding Event Handlers

How-to Register an Event Handler through C# code:

The following code allows you to register an event handler by making use of code. RunWithElevatedPrivileges isn’t always necessary, but I added it to it so that you know that you can’t run the code in an application page as a user who doesn’t have the necessary rights.

SPSecurity.RunWithElevatedPrivileges(delegate()

{

   impersonateweb.AllowUnsafeUpdates = true;

   _spListAanwezige.EventReceivers.Add(SPEventReceiverType.ItemAdded, "Namespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=61942ef99a051977", "Namespace.EventClass");

   _impersonateweb.AllowUnsafeUpdates = false;

});

How-to see if your event handler is deployed properly to the list:

Out of the box SharePoint doesn’t display if your event handler is correctly hooked to a list. I make use of SharePoint Inspector(http://www.codeplex.com/spi) to check out my SharePoint Farm. To see if something is hooked to your list go to the following structure in your SharePoint Inspector to check out which events are registered to your list:

image

Tags van Technorati: ,,

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

Getting the SPUser Property at an event

Posted by koenvosters on July 30, 2009

Lets say we have a list containing the attending people of a meeting. On the same site we also have a list of the people that are not attending the meeting (absent). To make sure people that are on the attending list aren’t put on it twice, the obvious choice is to create an eventhandler that checks if the user is already in either of the list. Piece of cake. Or not? The code to achieve this seems quite obvious:

public override void ItemAdding(SPItemEventProperties properties)
        {
            
using (SPWeb web properties.OpenWeb())
            {
                CheckForDoubles(properties, web)
;
            
}      
        }
        
private static void CheckForDoubles(SPItemEventProperties properties, SPWeb web)
        {
            SPUser user 
web.AllUsers.GetByID(Convert.ToInt32(properties.AfterProperties["Persoon"]));
            
SPList attendinglist web.Lists["Attending"];
            
SPQuery query = new SPQuery();
            
query.Query = string.Format(“<Where><Eq><FieldRef Name=\”Persoon\” /><Value Type=\”User\”>{0}</Value></Eq></Where>”, user.Name);
            
SPListItemCollection attendingitems attendinglist.GetItems(query);
            
SPList absentlist web.Lists["Absent"];
            
SPQuery queryafw = new SPQuery();
            
queryafw.Query = string.Format(“<Where><Eq><FieldRef Name=\”Persoon\” /><Value Type=\”User\”>{0}</Value></Eq></Where>”, user.Name);
            
// execute the query    
            
SPListItemCollection absentitems absentlist.GetItems(query);
            if 
((absentitems!= null &;&absentitems.Count >0) || (attendingitems != null &;&attendingitems.Count >0))
            {
                properties.ErrorMessage 
= string.Format(“The user {0} is already in the attending or absent list.”, user.Name);
                
properties.Status SPEventReceiverStatus.CancelWithError;
                
properties.Cancel = true;
            
}
        }

And it worked perfectly on my dev box. But for some reason, when deploying it to the acceptance/test environment, this piece of code no longer worked. After checking out the afterproperties (see my other post) I found out that instead of the ID I was getting ;1#domain\username back in the acceptance environment. I haven’t quite figured out why, but to solve it for both systems (and to prevent problems in the future), I changed the code to:

SPUser user;
            if 
(properties.AfterProperties["Persoon"].ToString().Split(‘#’).GetLongLength(0) > 1)
                user 
web.AllUsers[properties.AfterProperties["Persoon"].ToString().Split(‘#’)[1]];
            else
                
user web.AllUsers.GetByID(Convert.ToInt32(properties.AfterProperties["Persoon"]));

Posted in Development, SharePoint 2007 | Leave a Comment »