Archive for the ‘SharePoint’ Category

While working on a SharePoint solution, I was plagued by intermitant problems where the solution failed to deploy because of not being able to locate an Assembly. Looking at the VSeWSS1.3.log file the following entry was present:

Microsoft.SharePoint.Tools.Utilities.VSeWSSServiceException
Microsoft.SharePoint.Tools.Utilities.VSeWSSServiceException: VSeWSS Service Error: Feature 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' could not be installed because the loading of event receiver assembly "..." failed: System.IO.FileNotFoundException: Could not load file or assembly '....' or one of its dependencies. The system cannot find the file specified.
File name: '....'
   at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.Load(String assemblyString)
   at Microsoft.SharePoint.Administration.SPFeatureDefinition.get_ReceiverObject()

When I checked the GAC this Assembly was there and when looking at the solution Manifest.xml there was an entry for the ‘missing’ Assembly.

In the solution I had a list definition that was to be bound to a feature activated event. After numerous attempts and poking around in the files I found that an entry had appeared in the content type Feature.xml file that the list defintion was based on trying to bind that Content Type feature to a feature activated event. After removing the offending ‘RecieverAssembly’ and ‘RecieverClass’ attributes the solution deployed fine.

In short, the message from VSeWSS was not clear. It complained that the Assembly was missing but what was actually the problem was that a Content Type was linked to a feature reciever that it shouldn’t have been! I still don’t know how the content type got bound to a feature activated event though….

I recently created a new master page and deployed it as a feature to my SharePoint site following the articles from Heather Solomon (Create a Feature: Master Pages for Site Collections) and Chakkaradeep (SharePoint WCM – Breaking the Ice – Building the initial Master Page). I deployed the feature and activated it on my Site Collection. The next step was how to set the master page.

Both these articles explain how this is done – via the ‘Master Page‘ option under ‘Look and Feel‘ on the ‘Site Settings‘ page. Quickly going to this page I hit a major problem – it wasn’t there. After doing a quick dig around I found out why – it is only available on a ‘Publishing Site‘ by default and my site collection root site was a ‘Blank Site‘. What was I going to do – I didn’t want to have to go into every site and change the master page using SharePoint Designer manually? 

After a bit of further digging I found the solution. Within the ‘Site Features‘ on the ‘Site Settings‘ page there is a feature called ‘Office SharePoint Server Publishing Infrastructure’. When activated this provides the options to manage master pages on your SharePoint sites. Of course, as is alluded to in the above articles this feature is only available in MOSS and not in WSS .

When creating content types for WSS and MOSS you quickly hit a problem when trying to define a Lookup column that references itself or another list. This is caused by the fact that the ‘List’ attribute references the unique identifier of the list that it is referencing and not its name.

When I tried to find a solution to this problem I came across a couple of interesting resources. The first was an article by Hristo Pavol called ‘Lookup Fields to the same list‘ in which he posits that you can just provide the value ’self’ to make the column reference the current list. I could not get this to work and so I looked at another solution by Chris O’Brien which he has made available on CodePlex – http://sp2007lookupfields.codeplex.com/ - which is based on his article ‘Creating Lookup columns as a feature‘. This uses the feature activated event of a list that is based on the content type that I had defined.

I tried this solution and managed to get it to work but of course it creates a Site Column and did not add the column to the list which is what I wanted. Using Chris’ code as the basis I came up with the following that finds the list and adds the lookup column that references itself to the list:

    public class PortfolioListFeatureReceiver : SPFeatureReceiver
    {
  
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
                SPWeb currentWeb = null;

                currentWeb = properties.Feature.Parent as SPWeb;

                using (currentWeb)
                {
                    SPList referencedList = currentWeb.Lists["Portfolios"];
                    string columnDefintion = "<Field ID=\"{8D626343-FEBE-438b-B76E-8CEC89EA9A9D}\" Type=\"Lookup\" Name=\"PortfolioParent\" DisplayName=\"Parent\" List=\"{" + referencedList.ID.ToString() + "}\" ShowField=\"LinkTitleNoMenu\" UnlimitedLengthInDocumentLibrary=\"FALSE\" Hidden=\"FALSE\" Required=\"FALSE\" Sealed=\"TRUE\" DisplaceOnUpgrade=\"TRUE\" />";
                    string fieldInternalName = referencedList.Fields.AddFieldAsXml(columnDefintion);
                    SPFieldLookup lookupListField = referencedList.Fields.GetFieldByInternalName(fieldInternalName) as SPFieldLookup;
                    lookupListField.LookupWebId = currentWeb.ID;
                    lookupListField.Update();
                }
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {

        }

        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {

        }

        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {

        }
    }

This code is placed in a seperate assembly from the one containing your Content Type and List  Definition. As this Assembly needs to go in the GAC it also needs to be Strong named. To associate this Feature Reciever with your list defintion you need to add the RecieverAssembly and RecieiverClass attributes to the Feature element in the feature.xml file for your list definition:

<Feature Id="guid" Title="ListDefinition" Scope="Web" Version="1.0.0.0" Hidden="FALSE" DefaultResourceFile="core" ReceiverAssembly="AssemblyName, Version=Assembly Version, Culture=neutral, PublicKeyToken=Assembly Public Key Token Value, processorArchitecture=MSIL" ReceiverClass="AssemblyName.PortfolioListFeatureReceiver" xmlns="http://schemas.microsoft.com/sharepoint/">
   <ElementManifests>
    ...
  </ElementManifests>
</Feature>
Subscribe to Infinite Dreamers