Koen’s Weblog

SharePoint developer with a life!

Archive for the ‘Moss 2007’ Category

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 Moss 2007 | 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, Moss 2007, 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 Moss 2007, SharePoint | Tagged: | 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, Moss 2007, SharePoint | 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 Moss 2007, SharePoint | 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, Moss 2007, SharePoint | 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, Moss 2007, SharePoint | 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, Moss 2007, SharePoint | Tagged: | 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, Moss 2007, SharePoint | 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 Development, Moss 2007, Moss 2010, SharePoint | 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, Moss 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, Moss 2007 | Leave a Comment »

Getting the values of the AfterProperties of an event

Posted by koenvosters on July 30, 2009

As I was having some troubles with a different behavior between Development and Acceptance (AfterProperties["FieldName"] was giving errors in Acceptance but not in Development) I had to figure out a way on how to display the values in the AfterProperties.  In the end, I came up with this, which requires you to add ”using System.Collections;”

foreach (DictionaryEntry de in properties.AfterProperties)
            {
                EventLog.WriteEntry(
“MOSS 2007 Test Properties”“key:” + de.Key + “- value:” + de.Value);
            
}

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

Removing the thousand seperator from a YEAR calculated value

Posted by koenvosters on July 30, 2009

If you wish to remove the annoying thousand seperator from a YEAR calculated column use this formula:

=TEXT(YEAR([YourDateField]);”0″)

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

Automated builds using VSeWSS 1.3

Posted by koenvosters on July 9, 2009

I stumbled upon this post from John W Powell explaining how to create a nightly build using the Visual Studio Extensions for WSS 3.0. Exteremely interesting and something I’m gonna try out later this week. Let’s hope it’s a bit easier to do so in VS 2010 with MOSS 2010 :)

Posted in Moss 2007, Team System | Tagged: , | Leave a Comment »

Authentication problem on MOSS (login box keeps popping up)

Posted by koenvosters on June 18, 2009

Today I had a rather weird problem at a client. Whenever he tried to log on to his new extranet he had a login box coming up constantly, whatever he clicked on. First thought were changing the browser settings to automatically log in when on an intranet, but that didn’t fix it. When I connected to the site everything did work perfectly, so I still searched for a client setting. When checking out online I got some information about this error popping up when you have external content on your site. That was not the case, everything was local. The only thing on the site that wasn’t OOTB were the design elements. Just to try, I removed the design elements. The user tested and the login box disappeared, everything was working just fine. First idea was to check the security of the _layouts folder, but the standard SharePoint images were working just fine, so it couldn’t be the folder. I decided to check out the images in the 12 hive to see if there was something weird with them. And there it was, appearantly by copying the images to the 12 hive only the administrator had read/write acces to the images. Giving the authenticated users reading rights on the images fixed the issue.

Posted in Moss 2007 | Leave a Comment »

Access Denied when using hostname (search and site) on MOSS 2007.

Posted by koenvosters on June 15, 2009

Lately I’ve ran into a weird bug that appearantly has to do with the Windows Server 2003 Service Pack. When I tried a SharePoint site with http://spdev1:35000 everything worked like a charm. However, if I used a hostname http://customerdemo then all of a sudden I got Access is denied. As I used the administrator account with full access that was quite weird. As I didn’t get into SharePoint it meant that the problem had to be in IIS. After looking up some stuff I came to a Microsoft hotfix that sorted my problem : http://support.microsoft.com/kb/896861

That hotfix does not really mention the hostname problem, but it does fix the problem. Method1 is what you should go for on a production environment, Method 2 is what you can use on a dev box.
Method 2:

Method 2: Disable the loopback check

Follow these steps:

  1. Click Start, click Run, type regedit, and then click OK.
  2. In Registry Editor, locate and then click the following registry key:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
  3. Right-click Lsa, point to New, and then click DWORD Value.
  4. Type DisableLoopbackCheck, and then press ENTER.
  5. Right-click DisableLoopbackCheck, and then click Modify.
  6. In the Value data box, type 1, and then click OK.
  7. Quit Registry Editor, and then restart your computer.

I recalled seeing this solution on some other Belgian blog post by Sven Gillis. As it turns out there they linked it to the search no longer working (which in my case is quite normal as no account has access to the site). So if you get the following in your search you can use the above solution as well:
Access is denied. Verify that either the Default Content Access Account has access to this repository, or add a crawl rule to crawl this repository. If the repository being crawled is a SharePoint repository, verify that the account you are using has “Full Read” permissions on the SharePoint Web Application being crawled. (The item was deleted because it was either not found or the crawler was denied access to it.)

Posted in Moss 2007 | Leave a Comment »

InfoPath either cannot connect to the data source or the service has timed out.

Posted by koenvosters on March 10, 2009

This error is one we get confronted with quite a lot (especially our juniors :) ). As a clear fix isn’t really described out there I’ll put it here and hope it bubbles up on google :-)

If you are using http://localhost in your webservice url, use http://servername. That should do the trick.

Posted in Moss 2007 | Leave a Comment »

Approaches to Creating Master Pages and Page Layouts in SharePoint Server 2007

Posted by koenvosters on February 27, 2009

Andrew Connell (Microsoft MVP from the Ted Pattison Group) posted a new article on MSDN regarding the creation of master pages and custom page layouts. It explains the different (two) approaches that you can take to create them. Quite an interesting read, especially if you want to know the consequences (pro’s and con’s) of your choice.

Link : http://msdn.microsoft.com/en-us/library/dd164422.aspx#MOSS2007CreatingMasterPagesAndPageLayoutsTwoApproaches

Posted in Moss 2007 | Leave a Comment »

Office 14 (Server and clients) delayed till 2010

Posted by koenvosters on February 26, 2009

Yes, about time to make a new post. I’ve been holding off posting to finish my Barcelona stories but there just aren’t enough hours in a day at the moment and this blog needs to stay alive :) On topic now : Steve Ballmer has confirmed that Office 14 has been delayed till 2010. As it is in TAP at the moment that was to be expected as there still needs to be a beta phase. I do hope it does come soon so I can start playing around with it!

Posted in Moss 2007 | Leave a Comment »

Tech Ed Barcelona : Dday – 2 (Road Trip)

Posted by koenvosters on November 8, 2008

As promised to my colleagues and friends I’ll be blogging about my road trip to Barcelona Tech Ed with my colleague Yanis Duwyn. This post is currently made from Yanis’ catacombs of his house. The car is ready, the tank is filled up, the laptops are ready and there is a big case of Red Bull in the trunk. I kissed my kid and girlfriend goodbye and got the typical concerned parent phonecall, which is always nice :) Wish me good luck, I’m driving with Camicaze Yanis for 16 hours, and I’m supposed to sleep while he is driving :)

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

tech ed Developers| 2008 I’ll be there – will you?

Posted by koenvosters on October 31, 2008

And it’s time for the alltime necessary post to let you know that I’ll be attending tech ed 2008 for Developers from 10 to 14 November in Barcelona Spain. I’ll probably will be following most of the MOSS 2007 sessions there and take a look at the future as well (what is coming, what is going on). I’ve seen that quite a few partners are there as well, so it’ll be a nice time to catch up. If you are interested to meet and have a beer (in Belgium we only drink beer :) ) let me know at “digitallion connected to an @ and then Microsoft’s email service (hotmail.com). Sorry about the cryptic message but I don’t want to be flooded with spam :) See you there!

 

Koen

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

Update Fantastic 40 released

Posted by koenvosters on October 31, 2008

Microsoft released an update to the “Fantastic 40″. The Fantastic 40 is a set of application templates for WSS 3.0. You can find them here. They include (a few examples):

  • IT Team Workspace
  • Call Center
  • Job Requisition and Interview Management
  • Change Request Management
  • Knowledge Base
  • Compliance Process Support Site
  • Lending Library
  • Contacts Management
  • Physical Asset Tracking and Management
  • Document Library and Review
  • Project Tracking Workspace
  • Enjoy!

    Posted in Moss 2007 | Tagged: | Leave a Comment »

    Setting the default Excel version for Export to Spreadsheet of Lists in MOSS 2007

    Posted by koenvosters on October 23, 2008

    Since I’m using two versions of Office at the moment, 2003 and 2007 I sometimes get updates which overwrite several settings, resulting in certain actions being opened in Exel 2003 instead of Excel 2007. One of the annoying things was the Export to Spreadsheet of SharePoint lists opening with Excel 2003 instead of Excel 2007. Smart as I thought I was, it would be the xlsx files opening with Excel 2003 (with compatibility pack) instead of opening them with Excel 2007. And yes, they were set to default opening with 2003. Problem solved. I thought :) The next export to spreadsheet resulted in opening in 2003 instead of 2007. What was the underlying problem. The iqy files (Excel Web Query Files according to my OS, although iqy stands for internet query) were set to default opening with 2003 as well. Changing that to Excel 2007 did solve my problem. Pretty straightforward to fix, but easy to miss. Hope this helps some people out there :p

    Posted in Moss 2007 | Tagged: | Leave a Comment »

    Filter Pack for Search

    Posted by koenvosters on October 22, 2008

    Microsoft released a new filter pack for Search. It will install and register IFilters with the Windows Indexing Service. It includes IFilters for the following formats: .docx, .docm, .pptx, .pptm, .xlsx, .xlsm, .xlsb, .zip, .one, .vdx, .vsd, .vss, .vst, .vdx, .vsx, and .vtx.

    Because Windows Desktop Search (WDS) consumes IFilters from Windows Indexing Service, the IFilters will be automatically registered and available for use by WDS. The following products that include search are supported:

    Posted in Moss 2007 | Tagged: | Leave a Comment »