Welcome to my blog on all things SharePoint. I have a range of articles that will interest you if you've made it as far as visiting my blog. I was awarded as an SharePoint MVP by Microsoft in July 2010. I currently live in New York and am an Enterprise Architect at AvePoint Inc.. I co founded www.NothingButSharePoint.com with Mark Miller in 2010.

MVP AwardJeremy Thake Profile Photo

Whitepapers

NBSP

Check out my articles on NothingButSharePoint.com

Solution Development in SharePoint 2007

This series was inspired by the chatter amongst SharePoint blogs on the best ways to approach customisations in SharePoint using Solutions.

Part 1 - Part 2 - Part 3 - Part 4 - Part 5 - Part 6 - Part 7 - Part 8

Leveraging the SharePoint Platform

This series was inspired by a discussion had with Andrew Coates at a Perth SharePoint User Group meeting. This then turned into a 6 part series on Arno Nell's SharePointMagazine.net web site.

Initial post - Part 1 - Part 2 - Part 3 - Part 4 - Part 5 - Part 6

Webcasts

I have recorded various web casts that I present at User Groups or just on a specific topic by request:
How ASP.NET Developers can leverage SharePoint webcast
SPSource Webcast: Reverse engineer Lists to ListTemplates and much more
SharePoint Development with Unit Testing webcast
Perth SharePoint UG Web Cast on approaches to deploying artefacts (SPSource)
More...


Podcasts

I have been interviewed about Leveraging the SharePoint Platform by the SharePoint Pod Show: listen here .

RSS Feed Feed your read!

Archives

November 2012 (6)
October 2012 (8)
September 2012 (4)
August 2012 (7)
July 2012 (13)
June 2012 (4)
March 2012 (1)
February 2012 (1)
January 2012 (5)
September 2011 (2)
August 2011 (1)
July 2011 (3)
June 2011 (7)
May 2011 (3)
April 2011 (3)
March 2011 (3)
February 2011 (2)
January 2011 (1)
December 2010 (4)
September 2010 (4)
July 2010 (5)
June 2010 (4)
May 2010 (6)
April 2010 (7)
March 2010 (5)
February 2010 (7)
January 2010 (3)
December 2009 (1)
November 2009 (6)
October 2009 (9)
September 2009 (7)
August 2009 (6)
July 2009 (13)
June 2009 (4)
May 2009 (12)
April 2009 (4)
March 2009 (4)
February 2009 (13)
January 2009 (4)
December 2008 (4)
November 2008 (11)
October 2008 (16)
September 2008 (4)
August 2008 (5)
July 2008 (4)
June 2008 (8)
May 2008 (5)
April 2008 (9)
March 2008 (5)
February 2008 (6)
January 2008 (1)
November 2007 (11)
October 2007 (8)
September 2007 (24)
August 2007 (5)
July 2007 (2)
May 2007 (1)
April 2007 (1)
March 2007 (1)
February 2007 (3)
January 2007 (4)
November 2006 (7)
October 2006 (7)
September 2006 (18)
August 2006 (14)
June 2006 (3)
May 2006 (8)
April 2006 (4)
March 2006 (38)
February 2006 (30)
January 2006 (2)
December 2005 (3)
November 2005 (28)
May 2005 (1)
April 2005 (5)
March 2005 (1)
November 2004 (1)
August 2004 (11)
July 2004 (1)
Failed to render control: An error occurred during a call to extension function 'createMonthUrl'. See InnerException for a complete description of the error.

Links

Tag Cloud

Ajax, Apple, DotNetNuke, Enterprise Content Management, Error Resolution, Gadgets, General, Governance, Microsoft .Net Development, Mobile, SharePoint, Sharepoint Business Forms, Sharepoint Business Intelligence, Sharepoint Collaboration, SharePoint Development, Sharepoint Enterprise Content Management, Sharepoint Enterprise Search, Sharepoint Portal, US Migration, Web 2.0, Workflow

Solution Development in SharePoint 2007 Part 2   

Tags: SharePoint
Technorati Tags:

Part 1 - Part 2 - Part 3 - Part 4 - Part 5 - Part 6 - Part 7 - Part 8

"Previously on 'Prison Break'...I mean 'Solution Packages for Developers'"

My blog got quite a few extra visitors over the last couple of days since writing about SharePoint Development and "doing things the right way". A few people have been giving me "gentle" and "subtle" hints to start a series and based on the success of Paul Culmsee's various part articles I've decided to give him a run for his money...but in a different space to his primarily focused on Developer land.

"Telling a real 'SharePoint Developer' from a 'SharePoint User'"

So as I was saying in my previous post...there is this notion of SharePoint Solution Packages with Features. These Solutions can be deployed to the SharePoint Farm no matter how big or small. The beauty of this is that it allows you to write these packages in Visual Studio in XML and .NET code which can be put into source controll and gives a paradigm of a snapshot of a "Solution" that is deployed in an environment.
The dangers of SharePoint are very apparent, any business user can create whatever they like if they are given Owner rights and before they know it, have thrown Excel in the bin to run their business in, and have lots of SharePoint Lists (SPList) and plenty of SharePoint Designer (SPD) workflows running. Imagine after four months, the User comes to you and says "I'd quite like it if it could do this". So any half respectable Developer would backup the SharePoint Site (Web) or SiteCollection (Site) that it has been set up in and then restore it in their development environment. The Developer makes his changes in the SharePoint interface and shows it to the User and they love it and want it in Production that afternoon...after all they were so close and it didn't take more than half a day to do their bit.

The Developer can't backup and restore into Production because Production has been in use since they last did their backup and it would mean losing data. Did the Developer write down every last interface step he did to get to the point he's at now? Does he really want to do that all over again in UAT environment for handover? Does he then really want to do that all over again in Production? How long are these steps going to take? Is there a risk of forgetting something or configuring it incorrectly? Is this going to mean more than 10 minutes down time in Production and therefore out of hours work...you bet your last Rolo it does!

"No it won't take the same amount of time to create it in a Solution!"

So SharePoint gave us Solutions to allow us to guarantee that whatever is installed in one environment is the same as the next. Wouldn't it be nice if you could just point at the Development environment and click "create me a solution for all of this". "Yes, Jeremy, it'd be really nice". OK...now we're past the unrealistic expectations of Microsoft lets get with reality.

There is a platform here to do these things and there is considerable SDK documentation on the APIs....there isn't considerable documentation and samples for using the APIs. If you do a search for "SPLimitedWebPartManager" in Google/Live and see how many results come back that aren't SDK API pages (diigo) you'll notice hardly any results. This Manager is one of the core ways of adding/removing/modifying Web Parts on a page. For me this is one of the most obvious, key parts of any Solution Deployment you would try and write to automate your work. The samples go as far as deploying the Web Part to the Web Part Gallery, but do not show you how to easily add them to the page or modified existing ones or delete ones you don't require.

"Next Week on 'Battlestar Gallactica', I mean 'Solution Packages for Developers'" 

In the next few weeks (before I jet set away for 3 weeks - don't worry I'll be back with more) I'll be posting some key scenarios that are done every day in the SharePoint User Interface, but replicated as deployable Solutions. I'll be using the tools mentioned in the last post and pointing to various resources for further information.

In the beginning...

To get your taste buds rolling, I thought I'd get started with one...and no I'm not doing "Hello World!". I'm going to show you how to deploy a SharePoint List (ListTemplate and ListInstance) completely in a Solution and I'll even throw in a Content By Query Web Part to display some data. Content By Query Web Parts are awesome, period (diigo). They can do so much...as Andrew Coates was saying at the last SharePoint User Group in Perth..."Leverage the Platform". Why write a web part in custom code to render a SharePoint List with a filter when you can use what's there OOTB. Yes I know it has it's limitations and I know Sezai will be throwing things at me next time he sees me. But seriously...lets not make things complicated "cos I can"..."Keep It Simple Stupid!" (KISS). They are a great way to leverage information by using Content Types and are proven to perform - Waldek Mastykarz clearly has more time on his hands than me to get this amount of evidence on it! I also have to give heaps of credit to "Mr STSADM" (Gary Lapointe) for giving plenty of sample SharePoint API codes which kick started in the right direction as there was hardly anything out there on this

"Chapter One – Business User Land" 

The Business User creates a List in a Site to store information on TV Shows with their "Season Number", "Episode Number" and "Air Date". The homepage of the Site will display the List in a web part along with other web parts not related to this project.

Now in the SharePoint User Interface the User would go to Site Actions, click on Create, select Custom List, create their list, create the columns, adding the List View Web Part, etc. Maybe ringing the Development team for support at various stages and expect instant help. I've uploaded a recording of this in action.

Resources needed

Business Users (5 minutes)

  • Create List with custom Columns
  • Create List View Web Part

"Chapter Two – Designer Land"

The Business User has gone to the IS department and isn't happy with how it is being rendered and wants to move away from a list like display to have headings and information render in a specific way.

So now the Designer goes away and takes a look at the List and creates a Content By Query Web Part and uses XSLT to render it how the Business User has asked. I've uploaded a recording of this in action also.

Resources needed

Designer (15 minutes)

  • Creating xsl:template elements for stying Content By Query Web Part and formatting the custom columns
  • Modifies the Content By Query Web Part .wepart XML to expose the custom columns and re-imports it

"Chapter Three – Developer Land"
So now the Business are really happy with this, but so far this has all happened in Production system and hasn't allowed Designers the ability to test that the rendering is going to work or that if they needed to add new columns etc it hasn't affected the Businesses day to day running. Chapter Three, allows you to get to this scenario.

In Developer land I would advise doing the same thing in some circumstances as the first two Chapters, even when you are a dab hand at coding straight away, but there are some design decisions to make at this stage.

Design Decisions

  1. Site Content Types (and Site Field Types) vs. List Instance Columns
    Columns will mean you cannot chose the List columns in the Content By Query Web Part when sourcing, grouping and filtering also may be re-use in Field Types in later developments.
  2. List Templates (with a List Instance) vs List Instance
    List Instance will mean losing the ability to customise the Forms used with the List (in following posts I'll explain this further) – you'd simply have a ListInstance with Rows defined and no hook up to Content Types or custom forms and inherently workflow or records policies also.
  3. Content By Query Web Part vs. List View Web Part
    List View Web Part won't allow for complete custom rendering to look non-SharePoint like...also can create custom CAML queries to filter and sort data in a more powerful way and also source data from multiple Lists over multiple sites over multiple Content Types.
  4. SPLimitedWebPartManager vs. AllWebParts
    The advantage of using the API in the FeatureActivated event rather than using the Module Element of the Elements Manifest. I find there is more control and also, exporting the .webpart XML hard codes the List Guids which can be dynamically entered using the API.

NOTE: I'll be putting up a webcast of this chapter tomorrow evening with full source code listings.

So, the Solution requires the developer to create a Site (SPWeb) using the "Publishing Site" Site Template called "TV Show Schedule". The Site will have a SharePoint List Instance (SPList) with the ability to add a List Item (SPListItem) of a "Schedule" Content Type with "Season Number" (Int), "Episode Number" (Int) and "Air Date" (DateTime) extra column metadata (SPField) based on a created List Template (ListTemplate). The front default.aspx page (SPFile) will have a Content By Query Web Part that will display these items Grouped By "Title" and Sorted by "Air Date".

Resources needed

Designer (15 minutes)

  • Creating xsl:template elements for stying Content By Query Web Part and formatting the custom columns

Developer (2 hours)

  • Create a ListTemplate set of creation scripts
  • Create a Content Type set of creation scripts
  • Create a Field Type set of creation scripts
  • Create a Content By Query Web Part to render on default.aspx
  • Create a Solution package to deploy the Solution Feature to the Site Collection
  • Create a install script to deploy the Solution to the Farm, create the new site and activate the Feature

Walkthrough

Content Types (ContentType)

I would agree with doing it in the UI first for Content Types too, purely for the Content Type ID which intelligently stores its parent information within it and is just easier to create a new one in the interface and copy it yourself. I use CT Feature Creator as it creates XML quite easily very similar to Solution Generator for both Site Content Types and Site Columns.

SharePoint Lists (SPList, ListTemplate, ListInstance)

First things first we need to imitate what the Business User did in Chapter One in a programmatic way. As an example of this...run up Solution Generator which is part of the VSeWSS install and point it at the Schedule List that is OOTB when activating the publishing feature. You'll get a heap of files...the relevant ones are the ones in the folder named the same the List itself and will contain a schema.xml file along with other .aspx files such as Upload.aspx etc. Anyone who can put their hand up and can script a ListTemplate schema.xml with Views, Fields, Content Types, Security and Forms from scratch without any references needs help! Debugging these things when you have an error is hard and it doesn't give you line numbers of where you've screwed up...so with Lists, do them in the User Interface and generate them.

Stuff to change

  1. Solution Generator also doesn't give it a unique Type ID in the ListTemplate definition placed in the Manifest file – although it seems to work fine. It appears these have to be unique when attaching Event Receivers and appears to have to be unique and less than 1000 - this can be used if we want to include this list in a custom site definition.
  2. Solution Generator does add instances of ContentTypes in list rather than ContentTypeRef's..urgh! Same with Fields...urgh! So you need to manually change these.
  3. It will also create folders with spaces in it which will break STSDEV and the Solution package itself, so you'll have to rename your ListTemplate's accordingly. For some reason it doesn't have the same behaviour as SPField and give you x_20_x in replacement of a space...who needs consistency I say!
  4. Solution Generator doesn't work on Site Definitions other than WSS definitions.
  5. You'll also notice that if you script it with the UI interface content type then generate the Content Type from script that it won't match up as the <Fields> elements are instances on the list...the inheritance creates a copy. So it's best to create the Content Type first then install this as a Feature on the Site and then create a List and use Solution Generator to script it.

Content By Query Web Part (ContentByQueryWebPart)

Again, even with this one, it's easier to get a CBQWP going via the User Interface than it is to guess what the minimum properties of the API object is to get the damn thing running! Although when you start wanting to show non-OOTB columns you have to do some behind the scenes work (an MSDN article covers this) – again this is something I wouldn't expect a business user to be able to do. So the dangers here is that they use other Web Parts like ListViewWebPart without realising the power of the ContentByQueryWebPart.

Once that's all up and running and you want to script this you can spend the next half hour guessing what API Property Name maps to what Web Part Property in the User Interface!

"Chapter Four: You took how long to @!?%@ do this!?!?"

I'm sure we've all been there...Development Managers asking why it's taken us this long to do it when he can do it in the interface in 5 minutes (ie. Chapter One). So here's some ammo:

Time Saved in Deployment

Although there is a considerable amount of effort involved in writing the Solution compared to generating it all in the Interface...in the long run, on large team projects and multi-environment scenarios it wins hands down.

Guaranteed same end result

With it being scripted, it means that the same Solution will be created in each environment.

Enforces standards

By forcing Developers to work in this way, it also ensures that everyone is working the same way. Microsoft is pushing this as a standard and as training courses start appearing for more than just "boot camps" these methods will mature.

Self-Documentation and reducing resource dependencies

It also ensures that everything is documented because if it isn't in the Solution package...it doesn't get installed into the next environment in the chain. So rather than relying on the Developer who developed it to deploy it to UAT, anyone can run the Solution package install.

Source controlled

By having the Solution in Source Control it ensures that if the initial Developer is sick for a week or his machine dies that all the work he's been doing is backed up and accessible to others.

Up to speed quickly

Fresh Developers on the scene can, from a fresh SharePoint Development environment, start pulling down the Solutions from source control and installing them and seeing how they fit together. Furthermore, once they're up to speed can work on the project.

Debugging

By being able to recreate these Solutions in any SharePoint Farm means you can test them in isolation and also their dependencies. On top of this you can get environments up for debugging and stepping through code very quickly to separate solutions to find out what is causing the issues.

Script load and performance testing

For the more advanced projects, you can then also load test and performance test the solutions in UAT before pushing this into Production. For more on this go over to Paul Culmsee's "Why do SharePoint Projects Fail?" series.

"Chapter Five: Happy Ending"

The sooner you educate the Users that it isn't simply a case of "smashing it out" in Production the better:

  • Messy/un-versioned master pages, page layouts, itemstyles.xml etc.
  • No distinction in projects on site – grouping web parts, lists, styles, content types etc.
  • High risk of deployments screwing up
  • Better use for SharePoint Developers time!
  • Undocumented Solutions appearing in Farms

"Chapter Six: Until next time"

So now we have a complete Solution which will deliver our scenario. In the next post I will go onto talk about getting a bit more complicated with the Content By Query Web Part and deploying some XSL and CSS as part of the package to "spruce" the Web Part.    

References

Here are a few references to the core MSDN/Technet links that I've used...it's worthwhile checking out my Diigo links also.

Solution 101

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

SDK Schema - http://msdn.microsoft.com/en-us/library/ms442108.aspx

Technet - http://technet.microsoft.com/en-us/library/cc263289.aspx

Feature 101

Feature.xml

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

SDK Schema - http://msdn.microsoft.com/en-us/library/ms475601.aspx

Technet - http://technet.microsoft.com/en-us/library/cc263360.aspx

Element.xml

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

 SDK Schema - http://msdn.microsoft.com/en-us/library/ms414322.aspx

Site Templates

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

Other good articles

  • Andrew Connell and Rob Bogue are in the process of a series of web casts...more information here. Rob has also followed up from a Q&A after the web cast with even more valuable information!
  • Chris O'Conner has just posted a similar series to what I am going to be doing here also.
  • Heather Soloman also has some great articles on this area.
  • Eric Shupps also has some kind advice on the subject.
 
Posted by  Jeremy Thake  on  6/3/2008
4  Comments  |  Trackback Url  | 0  Links to this post | Bookmark this post with:        
 

Links to this post

Comments


Peter Seale  commented on  Tuesday, June 03, 2008  8:50 AM 
I love all this. I'd also like to point you to another blog running along similar paths:
http://blumenthalit.net/blog/default.aspx

Specific posts I like:
* "Team Development in SharePoint" http://blumenthalit.net/blog/Lists/Posts/Post.aspx?ID=58
* What do I deploy? specifics - http://blumenthalit.net/blog/Lists/Posts/Post.aspx?ID=56

Anyway, as much as you have time+energy, definitely keep it coming :)


Sezai  commented on  Wednesday, June 04, 2008  1:45 AM 
Thanks for linking to this - http://blog.mastykarz.nl/2008/03/21/content-query-web-part-vs-custom-aggregation-web-part was a great read.

But yeh in general :

CQWP – I HATE XSLT and prefer rendering out html using a variety of other methods provided by ASP.NET. It still isn't flexible enough for use in internet sites with a completely custom design.

The dude produces the best results with his own Aggregation Web Part +

If you know how to implement caching in various ways you can get your own controls to perform better than the CQWP.

Eg. Media Release Archive page I built for NNTT makes use of CAML and SPQuery

http://www.nntt.gov.au/News-and-Communications/Media-Releases/Pages/Archive.aspx

This page is rolling up ALMOST 500 PAGES filtered where the date is before the current year.
When viewing the load time it's about 8s from here, which is quite fast considering what the page is doing behind the scenes.
It's fast due to custom caching.

Same as the search pages - http://www.nntt.gov.au/Future-Acts/Search-FA-Determinations/Pages/search.aspx the response is fast and this is over 2500 pages.

Depends what you are doing I guess – I'ld go with CQWP if it's a quick internal job and the requirements aren't specific about what html is rendered.


Ireland  commented on  Thursday, June 26, 2008  4:05 AM 
Nice Site!
http://google.com


  commented on  Monday, August 11, 2008  7:41 AM 

blog comments powered by Disqus