Schalk's evolutionary ramblings

Tortoise SVN whants your vote!

If you you Tortoise SVN, you should go vote for it as the best project and best tool for developers.

http://tortoisesvn.net

 

Posted by schalkvanwyk | with no comments
Filed under:

Stuff that VSeWSS hides...

This could be classified as a serious Duh! moment, but I noticed today that my features are published to the 12 hive with the name I have assigned in the WSP view in Visual Studio. This might seem like a rather obvious observation, but there is a tendency to forget what happens under the covers when one becomes dependant on the tools to do the job.

Thus something one need to be aware of is your naming convention for the features in the WSP view. Obviously certain file system rules apply, e.g. the length of the folder name, as well as the fact the name should be UNIQUE in the 12 hive. This might explain some of the issues I have been having, why could I not have noticed this earlier... The old SharePoint hands might know this fact off by heart, but this could endless pains for somebody using the WSP View of VSeWSS for the first time.

Hopefully this will serve as a reminder and maybe some help to any other SharePoint newbies out there.

P.S.
If all else fails read the documentation, especially the "SharePoint Development with Visual Studio 2008 for Windows SharePoint Services 3.0, version 1.3"

Posted by schalkvanwyk | with no comments
Filed under:

Umbrella Project

This .NET "helper" assembly has been around for a while, but I have never quite got to use it yet. Also, one does not find to many explanations of how to use the various classes and methods.

This post, Review: Umbrella project by the brainiac Oren Eini, aka Ayende Rahien, might help.

The Umbrella project can be found on CodePlex.

Posted by schalkvanwyk | with no comments
Filed under:

Mass Transit - A lean service bus

I came across this project in one of my feeds: MassTransit.

It seems well worth a look if you're a loosely coupled applications application developer. Otherwise just browse the code, it's quite fluent...

Tehre are also some reviews about it by Oren Eini aka Ayende Rahien (a true brainiac):
Reviewing Mass Transit
Review: Mass Transit Samples

Also have a look at NServiceBus for comparison.

Posted by schalkvanwyk | with no comments
Filed under: ,

SharePoint VSeWSS and feature dependency rules - Part 2: Follow up

So I got my features working after a long battle and struggling with VSeWSS deploying the solutions. So my features are setup as follow:

  1. A site feature to create the general (non-special) site fields.
  2. A site feature to create the general (non-special) content types
  3. site feature which creates the look-up list. (The look-up list will be used in site look-up fields)
  4. A site feature which creates the look-up fields referencing the look-up list. (Obviously this feature has to be dependant on the look-up list feature.)
  5. A site feature which creates the the more complex content types, containing the look-up fields which references the look-up lists.

This works, but I have some issues with it:

  1. Feature #3 is a site feature, which means the feature will be activated as a site collection feature, so the list will exist in the root site.
  2. I have 5 features to setup my site, because I can not get the elements in the features to activate in the correct order when the features are combined.
  3. I still had to create a feature receiver for feature #4 which would correct the "LookupList" property (or "List" xml attribute) on the look-up fields. (Frustrating that I had to do this even though I have modified the "List" attribute to point to the correct list by name, which does not work.)

Maybe there is something I don't know about regarding features and how the elements inside them are activated. Or it is VSeWSS that decides it knows better when it comes to building the solution file from the features.

Something I thought about while trying to get feature #4 working:
Why not have feature #3 update the look-up fields with the correct reference to the look-up list. All the names of the look-up list being installed will be available in the feature receiver, so I can resolve the id's of the lists. All I have to do is get all the look-up fields and re-assign the "LookupList" property to the correct look-up list, as I am already doing in feature #4. This should also make it possible to change feature #3 to a web feature, as well as get rid of feature #4, since it can be moved to feature #1 again. Kill 2 birds with one stone.

So some code:

public static void FixLooupFieldsRealtedToList(SPWeb web, SPList list)
{
    var fields =
        (from SPFieldLookup field in web.Fields.OfType<SPFieldLookup>()
         where
             field.Type == SPFieldType.Lookup &&
             String.Compare(field.Group, "_Hidden") != 0 &&
             field.LookupList != null &&
             field.LookupList.EndsWith(list.RootFolder.Name)
         select field).ToArray();

    foreach (var field in fields)
    {
        SPSProvisioning.FixLooupField(web, field);
    }
}

public static void FixLooupFields(SPWeb web, SPFeatureDefinition definition)
{
    foreach (SPElementDefinition elementDefinition in definition.GetElementDefinitionsOf(SPElementDefinitionType.Field))
    {
        string name = elementDefinition.XmlDefinition.Attributes["Name"].Value;
        SPSProvisioning.FixLooupField(web, name);
    }
}

public static void FixLooupField(SPWeb web, String fieldName)
{
    SPFieldLookup lookupField;
    if (!web.AvailableFields.CanGetField(fieldName, out lookupField))
        return;

    SPSProvisioning.FixLooupField(web, lookupField);
}

public static void FixLooupField(SPWeb web, SPFieldLookup lookupField)
{
    XElement fieldSchema = XElement.Load(new StringReader(lookupField.SchemaXml));
    string listName = fieldSchema.Attribute("List").Value;
    listName = listName.Substring(listName.LastIndexOf('/') + 1);

    SPList list;
    if (!web.Lists.CanGetList(listName, out list))
        return;

    fieldSchema.SetAttributeValue("List", list.ID.ToString());

    if (web.Fields.CanGetField<SPFieldLookup>(lookupField.InternalName, out lookupField))
        lookupField.Delete();

    string result = web.Fields.AddFieldAsXml(fieldSchema.ToString(SaveOptions.DisableFormatting));
}

Something to remember when switching your feature receiver from site to web is that the feature's parent becomes a SPWeb object instead of a SPSite object, the following method will get the SPWeb for the feature:

public static SPWeb GetWebFromFeature(SPFeature feature)
{
    SPSite site = feature.Parent as SPSite;
    SPWeb web = null;
    if (site == null)
        web = feature.Parent as SPWeb;
    else
        web = site.OpenWeb();

    return web;
}

Also, as far as I know you are not suppose to dispose the SPWeb object if it came from the feature, so for a web scope feature you don't dispose the SPWeb object. (Not sure about this one.)

I'm back to where I wanted to be, now to solve the business problem...

I think the next thing I need to do is stop using VSeWSS and rather use the tools on CodePlex. I think VSeWSS is great for starting of with simple projects, but as soon as things start getting complex, it starts failing.

Posted by schalkvanwyk | with no comments
Filed under:

SharePoint VSeWSS and feature dependency rules

I have been receiving the following error when I click deploy in VS using VSeWSS 1.3 (this is a simple deployment to my local development SharePoint):
"Failed to activate feature 'SiteScopeFeature - Fields' (ID: c66d8a1f-b5a6-469d-91f7-79542545a788) at scope 'http://spvm/'"
This is after modifying me features to hell and back to eliminate any possible issues the complex features could have.

So I opened the site in IE and decided to activate the features manually, all activated until the following error occurred:
"Dependency feature 'WebScopeFeature - LookupLists' (id: ef84c085-cabc-4834-a7f1-fcbcf542e1b9) is not properly scoped for feature 'SiteScopeFeature - LookupFields' (id: 14ff1c75-3ce1-4129-9272-f762d80bbafe). Its scope 'Web' must be equal to or higher than 'Site'."

OK! Great thanks for telling me that VSeWSS! NOT! Why could this not be validated during the packaging of the solution? Or at least tell me the actually reason the deployment failed. Instead I have to go look in the SharePoint log files, which is where I found the first clue to the issue, but it's a pain!

I found the following post where somebody else also had a similar problem:
Scope Dependencies for SharePoint Features

So the solution:
Change the scope of the feature it is dependant on to Site? OK, will try that.
Next error (this time from VSeWSS):
"Elements of type 'Receivers' are not supported at the 'Site' scope.  This feature could not be installed."

That's not going to work.

I'll make some lunch, think about it and come back to you.

So the situation is that I have a couple of features:

  1. A site feature to create the general (non-special) site fields.
  2. A site feature to create the general (non-special) content types
  3. web feature which creates the look-up list. (The look-up list will be used in site look-up fields)
  4. A site feature which creates the look-up fields referencing the look-up list. (Obviously this feature has to be dependant on the look-up list feature.)
  5. A site feature which creates the the more complex content types, containing the look-up fields which references the look-up lists.

The problem:
Feature #4, a site scope feature, is dependant on feature #3, which is a web scope feature. Changing feature #3 to a site scope feature give a error saying that event receivers cannot be activated in a site scope feature.

Find the event receiver (it is on one of the list, not suppose to be), remove it, but add the receiver and the contained code the content type representing the item in the list.
Try again. Still failing, this time with some other strange error, because the content type is being added to the list via the list definition. Why I tell you why?

No worries, get rid of the reference to the content type in the list definition and add it via the object model in the feature receiver.

  public override void FeatureActivated(SPFeatureReceiverProperties properties)
  {
            SPSite site = properties.Feature.Parent as SPSite;

            using (SPWeb web = site.OpenWeb())
            {
                SPContentType myItemContentType;
                if (web.AvailableContentTypes.CanGetContentType("MyItemContentType", out myItemContentType))
                {
                    SPList list;
                    if (web.Lists.CanGetList("MyLookupList", out list))
                    {
                        list.ContentTypes.Add(myItemContentType);
                        list.Update();
                        web.Update();
                    }
                }
            }
        }

That seemed to work. (Until the next issue pops up...)

I must say it help writing about a problem. One starts thinking about how you came to be in the situation you are currently in and the issues surrounding the problem.

 

Alternative Solution (the rantings version - don't read this if you are a sensitive SharePoint developer):
Develop using something else than SharePoint... That's the feeling I'm starting to get, since I spend more time trying to figure out why deployments don't work, instead of building the actual solution.

I've found most of my time spent on SharePoint development is not spent and designing the solution, but with the inconsistent xml definitions used in the features definitions. I've been very close to giving up on the xml generated for features and the solution file by VSeWSS, it just feels unworkable. I end up getting ridiculous errors (e.g. "Failed to activate feature 'SiteScopeFeature - Fields' (ID: c66d8a1f-b5a6-469d-91f7-79542545a788) at scope 'http://spvm/'" - WTF!!!! give me more detail!), just when I start getting to a point where I feel I understand how things work and that my features are actually deploying successfully. Every time this happens I have hold myself back, because I don't know what other issues I will be running into switching to using the feature activation event and the SharePoint object model.

I'm sorry but deployment of a solution should not be this difficult (I've not even got to production!!) and this will have to reworked and IMPROVED for SharePoint to become more usable from a developers perspective.

Why is this a common problem in MS products? Things always turn into a nightmare when it comes to deployment of custom solutions to there products.

Posted by schalkvanwyk | 2 comment(s)
Filed under:

Source Control with SubVersion (SVN)

I LOVE SubVersion (SVN) as a source control engine!

At the moment I am using VisualSVN for the server (just because it has got a admin GUI) and a combination of TortoiseSVN and the AnkhSVN plugin for VisualStudio 2008. These tools have grown up so much in the last year, it is unbelievable.

There is also a .NET API for SVN (SharpSVN) if you would like to manipulate SVN with .NET.

One should seriously consider SubVersion as a source control system if you don't have a proper source control system in place (that includes crappy SourceSafe). I think SVN is one of the better FREE alternatives if you don't have (or want) to spend the money on a expensive source control system.

However if you are looking for a more "reachable" source control, have a look at GitHub, your code online and always available.

I also make use of CodeKeep to keep track of my "special" code snippets. They have a Visual Studio add-in to make saving your code snippets easier.

Posted by schalkvanwyk | 2 comment(s)
Filed under: ,

Visual Studio Tip : Ctrl+Enter and Ctrl+Shift+Enter

Found this by accident, maybe it has been mentioned by somebody before:

In Visual Studio code editor, when you press Enter a new line is created where the cursor is positioned. (Nothing new about that)

When you hold Ctrl and press Enter, a new line is inserted before the line on which the cursor is currently positioned and the cursor is repositioned to the new line.

When you hold Ctrl + Shift and press Enter, a new line is appended after the line end of the line on which the cursor is currently positioned and the cursor is repositioned to the new line.

(This works in 2008 - C# configuration, don't know if this is applies to other configurations or previous versions)

Posted by schalkvanwyk | with no comments

Some more SharePoint development tools

I came accorss the following SharePoint developer tool by Imtech:
Imtech Fields Explorer Visual Studio 2008 plugin
One of the great feautres is that it can generate code from various SharePoint artifacts.

They also have a couple of other tools that could be very usefull:
Generating list instances XML using Imtech ListInstance Generator
SharePoint InlineSiteSettings

Posted by schalkvanwyk | with no comments
Filed under:

How to add trace (logging) to your SharePoint solutions

I came across this great idea on Scot Hillier's blog in the following article: Writing to the SharePoint Unified Logging Service. There is some more regarding this topic here: SharePoint Logging and Microsoft’s Trace Log Provider.

Maybe it would be a good idea to combine this with Enterprise Library to ensure separation of concerns (which can help with testing and moving your code to and from SharePoint), have a look at: Implementation of Logging and Instrumentation Application Block in MOSS 2007.

Posted by schalkvanwyk | with no comments
Filed under:

A good starting point for SharePoint

I am still finding it quite hard getting my head around creating a deploy-able solution for SharePoint, having only recently started digging into building solutions FOR SharePoint (previously I only regarded SharePoint as a "data" source/store that could do some nifty tricks). There are so many ways of getting things done and often the obvious ways provided in Visual Studio are out of date and rejected by the experts. Off course there is the patterns & practices SharePoint Guidance project on Codeplex, which helps one along, but in the SharePoint world things still ain't as clear cut. At least the code can be made cleaner by combining it with a good unit testing framework, e.g. TypeMock Isolator (Testing SharePoint - Now Easier with the New API).

Apparently the Visual Studio extensions for Windows SharePoint Services (VSeWSS) is also not good enough to do SharePoint development, no wonder I could not make head or tail about where to start developing deploy-able SharePoint solution. Have a look at these articles "What's Your Process for Developing SharePoint Features and Solutions?" and "Is VSeWSS 1.2 Ready for Prime Time?" on Scot Hillier's blog for a starting point to understanding how the SharePoint solution & feature world fits together. He also mentions some possible tools to help with the process, for one have a look at "Announcing AC's VS CodeRush/Refactor Tools for SharePoint Devs (Part 1 of 5)".

Then there is of course the future of SharePoint development with VS2010... Hopefully the tools will soon start helping developers make sense of the structured "mess" that is web development... (Don't get me wrong, I adore the foundations of web development, namely: IIS, APS.NET and the SharePoint platform, it's just a pity about the HTML stuff.)

For the moment I will have to figure out how Sharepoint solutions, features and feature stapling work and how create all of this with minimal support from the VS tools.

UPDATED:
This morning I also started reading "Solution Development in SharePoint 2007" by Jeremy Thake. So far it is a great read with plenty of links to articles and a number of resources.

Posted by schalkvanwyk | 6 comment(s)
Filed under:

"Document checked out" workflow issue in SharePoint document library

I've been getting the following messages logged to a workflow history "Error updating a list item" "Document checked out", this happens when a simple workflow is kicked off on a document library.

The solution to this problem might be common knowledge to the SharePoint experts out there, but it still took me some time before I even got to some meaningful answer, never mind a possible solution. Strangely enough, SharePoint seems to know that Office has a document open when you set the workflow to only be activated by the user and not when the item is created (you will notice this when you try to start a workflow on a item while it is still open in Office, SharePoint will notify you off the fact).

So what was I trying to do?

  1. Have a workflow start when a document is created in a document library by a user.
  2. The first step in the workflow will update a custom status field for the item.
  3. Next rename the item so that it makes more sense to the users.
  4. After that the rest of the workflow will continue with the other business processes - not relevant to this problem.

I ran the above workflow and had endless issues related to the document being checked out by the user, even though I did not have versioning turned on. I turned versioning on and added some actions to check the document out before I made changes to the document. This resulted in the workflow giving me a different error, the document has already been checked out. There goes that idea, remove the actions, now what? After some searching I came across the following possible solution: SharePoint Workflow: Error Updating a List Item

So I added a pause for n period (in my case 1min) to the first workflow step. This seemed to work great, but not always...
Create a new document, save it to the document list and don't close the document.
Now wait for a undetermined amount of time (since SharePoint does not know how long 1 minute is - something to do with the job scheduler and threads).
Once the pause has finished you will get the "Error updating a list item" "Document checked out" message logged in the workflow history until the document is closed or the lock times out.

It appears that it is not a serious error, since the worklfow will eventually continue processing, that is if you wait long enough.

I then had a great idea, it would be better to use a item added event handler and code the actions that set the initial value for custom status field and did the renaming of the document. So I created a new document in the document library and saved it, the event handler did it's thing, all's good. But the document was still open and I tried to save it again, this then caused a new document to be created in the document library since Office doesn't know that the document has been renamed. Crap! And there is no way to set any properties to tell Office that the document has been renamed. Double Crap!

So back to the workflow... And I thought there must be a way to know that the item is checked out by the user, yip check out: http://suguk.org/forums/thread/4063.aspx
In this thread "Maidstone" responds with a interesting comment and some code:

item.File.CheckOutStatus == SPFile.SPCheckOutStatus.None

Eurika, another tiny light at the end of  the dark SharePoint tunnel! Just what I was looking for, except that field is not freely visible a a field in SharePoint workflow designer, so I will have to create a custom workflow.

Some other guys also had similar ideas using the event handlers and loops with "Thread.Sleep" (not a ideal solution at all):

SharePoint Tip #17: Testing if an Office Document is Open
SharePoint Document Library Event Handlers & "Locked for Editing" Status
Updating Locked Files in SharePoint (using .NET Code)

So what about incorporating the above concepts in a custom workflow, since workflows can have a "passive sleeping loop". This can be done by adding a while activity, with a condition for checking the lock status of a document library file item. Also add a delay activity to the while activity and set the timeout duration to the "SPFile.CheckOutExpires" property's value, which results in less frequent checks to see if the lock has been released on the file. Another option could be to have a list or eventhandlerscope activity which can contain 2 delay activities to either check at a more regular interval and alternatively expire at the "SPFile.CheckOutExpires" value.

All this to get arround the Office to SharePoint document lock issue, insane!

The following post describes some other scenarios that also need to be catered for:
Document is locked for editing

There will be some more head scratching to follow...

Posted by schalkvanwyk | 9 comment(s)
Filed under:

Unstable SharePoint

Software development 101 (this will be the lesson learned today):
Backup your databases before you make a major change to a system, especially in your development environment. (I should know this by now...)

I've had SO many issues trying to get to grips with SharePoint as a application development platform, most of all it had to do with the  the actual OS environment - OK, maybe a Apple MacBook is not the best Microsoft development platform... On top off this SharePoint comes with a huge learning curve and it takes a enormous amount of time to wade through the loads of information and then process the information and put it into action.

The latest issue came out off nowhere. There I was, on my marry way developing a new solution with my new found friend, WSS, when out of the blue it slammed it's door shut on me. I spent a couple of hours trying to figure out what caused my development SharePoint to fall over and give me a big fat middle finger! IIS kept on asking me for a user name and password and then just said "Service Unavailable", with a heap off errors in the event log. I did not even do anything major, except install a feature from CodePlex, "SharePoint config store", I have a feeling it might have something to do with that - maybe I should have read the read-me.

I then spent another couple of hours trying to get back to the state I was before, wishing I had backed-up my SharePoint databases. Luckily I had a copy of the VPC, a little older, but good. I restored the databases (specifically the "SharePoint_Config" database) from there and I was back on track. I still wish I knew a better way to recover from this problem, but at the moment I can't afford researching the problem and would rather spend the time developing the solution.

If anybody has come across a similar issue, please let me know.

The following are the events logged in the eventlog:

Event Type: Warning
Event Source: W3SVC
Event Category: None
Event ID: 1009
Date:  20/01/2009
Time:  6:19:04 PM
User:  N/A
Computer: SPVM
Description:
A process serving application pool 'SharePoint - 80' terminated unexpectedly. The process id was 'xxxx'. The process exit code was '0x800703e9'.

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
 

Event Type: Warning
Event Source: W3SVC
Event Category: None
Event ID: 1011
Date:  20/01/2009
Time:  6:22:47 PM
User:  N/A
Computer: SPVM
Description:
A process serving application pool 'SharePoint - 80' suffered a fatal communication error with the World Wide Web Publishing Service. The process id was 'xxxx'. The data field contains the error number. 

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.
Data:
0000: 6d 00 07 80               m..€   
 

Event Type: Error
Event Source: W3SVC
Event Category: None
Event ID: 1002
Date:  20/01/2009
Time:  6:22:47 PM
User:  N/A
Computer: SPVM
Description:
Application pool 'SharePoint - 80' is being automatically disabled due to a series of failures in the process(es) serving that application pool.

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

I aslo see the following in the SharePoint log file (Don't know if this is relevant):

01/21/2009 08:44:08.96  OWSTIMER.EXE (0x0654)  0x0664 Windows SharePoint Services  Topology  888a Monitorable Can not find farm object in configuration database

Another tip for virtual development environments:
After having to deal with numerous Windows OS crashes and VPC/VM failures, I finally have a reasonable stable environment (I think, touch wood). If you are having problems with VM's switch off "Hardware Virtualization", if you are still having problems try and switch off your screen's "Hardware Acceleration". Well so far that works better for me - even though I loose some Windows/NVidia good looks.

SharePoint Manager 2007 - a developers friend

I'm sure the SharePoint guru's out already know about the SharePoint Manager 2007 tool, but I think this tool is great for those that have only recently started working with SharePoint.

I must admit I have only recently started using the tool, but so far it has helped me get to grips with complexities of the xml definition files used to configure SharePoint. Now I can change a setting through the tool's user interface and immediately see the outcome in the associated xml definition.

Download it here:
http://www.codeplex.com/spm

Also make sure you have a look at the P&P SharePoint Guidance, especially if you like to do "cleaner" SPS/MOSS development (if that's at all possible). It's given me some ideas and something to work towards - I hate having messy code, not to mention working with somebody else's mess...

Posted by schalkvanwyk | with no comments
Filed under:

I'm a typist and some very valid rantings

I though I can rant on about some things, then I came across this post: Programming's Dirtiest Little Secret, at least the writer touches on some valid points.

I actually came across the above post while reading the article We Are Typists First, Programmers Second by Jeff Antwood on Coding Horror, if you following some of the links in the post you will also find some other post with some very useful tips to improve your keyboard usage, to mention a few: Mouseless ComputingA Celebration of The Windows Key.

I have learned one new shortcut which I've been searching for since forever: windows key + B. Tadda! you get to the system tray! This always made me reach for the mouse (or the mouse keys if there is was no mouse).

I'm putting a dare out there, UNPLUG your MOUSE for a WEEK.

I've had to do it when I found out the mouse and keyboard they sold me was PS2 and there's only one PS2 port on the my super duper computer (which used all my money so I could not buy a adapter). I also found the biggest keyboard stumbler to be IE and websites, impossible to only use the keyboard, luckily there are mouse keys, but that's so sssslllllooooowwwww.

Posted by schalkvanwyk | with no comments
More Posts Next page »