Monday, February 12, 2007

European SharePoint Conference, Day 1

Today was the first day of the European (EMEA) SharePoint Conference in Berlin, Germany. As we have recently expanded into the UK, we are now officially a 'global' company (there's a scary thought for you) so we took this opportunity to join our mates from jolly ol' England on a jaunt across the Old Country. I have to say that I am quite impressed by the overall experience - if there were any doubts that SharePoint is a serious application around the world, let them be dispelled here and now. With more than 2,300 attendees (that's nearly twice as many as we managed to cobble together in the States last year) from 40 countries and 90 partners and vendors, it was quite a show. Read on for a summary of the day's events.

BTW, Southwest could learn a few things from SN Brussels Airlines. Like, how about some free chocolates on each trip instead of crappy peanuts, eh Mr. Kelleher?

Opening/Keynote

The Microsoft team kicked off the conference with a five-minute introduction in German (to the delight of the local audience, I might add) which left most of us scratching our heads and saying 'Was is das?'. The 'Wow is Now' video has long since jumped the shark, but the first speakers were energetic enough to make up for it. The catchphrase of the day was 'Ich bin ein SharePointer'. Say that a few times after a couple of Hefeweizen!

Derek Burney

There were quite a few Redmondites around - especially on stage and in the ubiquitous orange speaker shirts - and Derek Burney was first up (with an able assist from Mike Fitzmaurice). He laid some good numbers on us, like license count now exceeding 80 million worldwide and the official size of the internal Microsoft SharePoint deployment: 325,000 portals, sites and subsites comprising more than 12TB of data (who gets to back that up, I wonder?). It was interesting to note that on his slide promoting 'major' companies who had adopted SharePoint, three of the ten are based in Dallas :-)

Mike revealed publicly what had heretofore been confidential, so I can now tell you that sometime next month MS will unveil the official SharePoint Community Portal. Lawrence Liu gave us a rundown of this last week at the UK SharePoint User Group meeting (what, you weren't there?) and it's plenty slick. Just a beta right now but it will be live soon.

They closed with the most ridiculous commercial I've ever seen - a takeoff on those Total cereal ads where they claim that everything and the kitchen sink is in 'just one bowl'. It came complete with a corny jingle and sleazy used-car-salesman actor. Ok, I get the message, but was this really a good use of marketing dollars? Really?

Patrick Tisseghem, Part Eins

I always enjoying listening to Patrick as 1) he knows his stuff, and 2) he's a good presenter. And you just gotta like a guy whose every demo has something to do with beer. Patrick gave the standard rundown on using the object model, talked about garbage collection and good coding practices, and highlighted a bit about working with web services. He covered impersonation pretty well, which I think was lost on most everyone present, and even talked a bit about CAML and SPSiteDataQuery. Although he gave an explicit warning about using the DataQuery object to collect list data instead of looping through the SPListCollection, he did not voice similar concerns about using the object model to loop through SPWeb objects. In fact, he showed us how to do it (albeit briefly) and moved quickly past it.

I suppose I'm destined to be the lone voice in the wilderness on this issue, so let me state it once again in case anyone missed it the first thousand times - DON'T DO THIS! EVER! Unless you know for a fact that you'll never have more than a hundred or so sites in a site collection, this is bad, bad, bad. The overhead of GetSubwebsForCurrentUser and its equivalent(s) is tremendous and should be avoided like the plague. I know that's how it's shown in the SDK but you don't believe everything you read, do you?

Multilingual Working Group

Aside from the bizarre evening entertainment (see below) this was the highlight of the day. We don't think much about it in the States but this is a real pain point for many customers, especially throughout Europe where they often have to support three, four, five or a half-dozen languages at once. Hats off to Microsoft for realizing the severity of the issue and soliciting feedback and advice from partners and users. A couple of partners and myself gave 'em an earful for an hour (I also harped on Lawrence about this last week, so if you're reading this Al, that one's for you!). We came out with some good ideas and even a few suggestions for the workgroup sponsors to take back to Microsoft. We also agreed that since C# seems to be a universal language we are all now adding it to our resumes (CV's) immediately. And no, in case you're wondering, there is no Redneck Language Pack forthcoming in this or any future release, so y'all will have to just go on scratchin' yer heads at my vocabillary.

Content Types and Metadata

Good topic, wrong audience. This was supposed to be on the developer track and although Dustin Friesenhahn gave a good presentation it was all foam and no beer. There were only a couple of slides that even showed a smattering of code - the rest was all point and click. Nice for the IT guys but not what we hardcore OM types were looking for. General disappointment was expressed by all.

Patrick Tisseghem, Part Zwei

After that letdown, we needed some real code to perk us up, and Patrick didn't let us down. Some genius assigned him the topic of Templates, Definitions and Solution Deployment and only gave him an hour - now that's just plain wrong. I could talk for an entire day on any one of those subjects and I don't have all of Patrick's demos and SmartArt. He did an admirable job walking the group through custom site definitions and deployment - not an easy topic even for intermediate coders. Lots of great code samples and the ever-present Beer Team site.

Dinner and Entertainment

The Hotel Estrel Convention Center is reminiscent of Vegas-style auditoriums - lots of multimedia and light shows. After Patrick's final presentation a swarm of worker bees descended upon the room and cleared more chairs in five minutes than were on the entire deck of the Titanic. There's something to be said for German efficiency. While we all wandered off for a beer or two (konnte ich Schofferhofer bitte?) they turned out the 'rounds and we piled back in for some free victuals. I can't say much for the food - it was typical bland conference style fare meant not to offend anyone - but when the lights went down after the meal things go interesting.

Turns out the Estrel is the home of a popular Vegas-style musical review called Stars on Stage. Before we knew what was happening, a pre-Bobby Brown Whitney Houston was belting 'em out on stage, complete with scenes form her music videos and the requisite clips from Bodyguard during 'I Will Always Love You' on the big screens. Without a chance to catch our breath (or keep from falling over with laughter) were were hit in succession with Madonna, Boy George, Louis Armstrong, Tina Turner (who looked awfully like Whitney in a different wig) and finally, as you would expect, Elvis himself. I'll give 'em this - they were pretty damn good, especially considering they didn't have the best acoustics to work with and a stage with no Vegas flair (but some might fine-looking backup dancers). Louis Armstrong was simply amazing - right down to his facial expressions and the gap in his front teeth, this guy has it down, you dig? And all of this with a gigantic Office SharePoint Server 2007 sign in the background. Now don't that beat all?

So that's a wrap for day one. I'll post pictures as soon as I can get a reliable WiFi connection (don't even get me started on Internet access over here). And before I collapse for the night, a hearty "Salut!" to my new friends from Romania, Reka and Marius, and "Moien" to David and Razvan from Luxembourg.

Gute Nacht!

Friday, February 02, 2007

Creating a Basic Site Definition in SharePoint 2007

Creating a site definition from scratch in SharePoint 2007 is no easy task; easier, certainly, than it was in 2003, but in some ways even more complex. Perhaps the most confusing new element to creating site definitions is the use of FEATURES. There are some great articles on what FEATURES are and how to use them (see here, here, and here) so do a little homework before you get started.

Unfortunately, the built-in WSS templates don't use the time-saving and oh-so-handy Publishing features of the portal definitions, so you'll have to create your own definition if you want to apply any customizations beyond basic style overrides. To get you going in the right direction, here's a handy little guide on creating a very basic site definition from scratch. Let's first assume that you want a custom Team Site - nothing fancy, just something you can style and modify without impacting the default definitions.

Begin by performing the same steps you would have done in 2003. Navigate to the \12\Template\SiteTemplates directory (the 60 hive is dead; long live the 12 hive). Copy the 'Sts' folder and rename it - say 'CUSTOMSITE' for this example. Next, find the WEBTEMP.XML folder in \12\Template\1033\Xml. Open it in Notepad and add a new Template node to the end, like so:

< Template Name="CUSTOMSITE" ID="1001" >
< Configuration ID="0" Title="Custom Web Site" Hidden="FALSE" ImageUrl="/_layouts/images/stsprev.png" Description="Customized site definition for My Team Site" DisplayCategory="Collaboration" > < /Configuration >
< /Template >

* Note: The same numbering conventions apply in 2007 as in 2003 - set your Template ID to something greater than 1000 and the first Configuration node should always start with '0'.

Save the file and do an IISRESET at the command prompt. This is all you really need for a basic site definition but, as you will discover if you create a new Site Collection using this new definition and open it in SharePoint Designer, there are some things missing. Some very important things, actually, like the DefaultLayout.aspx page (look in /_catalogs/masterpage and you'll notice that only the default.master page is present). Without DefaultLayout.aspx you'll be able to modify the master page but not the central content area of your site. Oops. What happened?

As I said at the beginning, it's all about the Features. In this case, not only does the ONET.XML file determine what Features are provisioned as part of the site, there are also Features which determine what goes into a site that have nothing to do with the site itself - they are system Features that SharePoint uses when provisioning all sites.

To make sure that your new Site Definition has all the right pieces and parts, navigate to the \12\Template\Features\BaseSiteStapling folder and open BaseSiteStapling.xml in Notepad. It should look something like this:

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

< FeatureSiteTemplateAssociation Id="B21B090C-C796-4b0f-AC0F-7EF1659C20AE" TemplateName="STS#0" / >
< FeatureSiteTemplateAssociation Id="B21B090C-C796-4b0f-AC0F-7EF1659C20AE" TemplateName="STS#2" / >
< FeatureSiteTemplateAssociation Id="B21B090C-C796-4b0f-AC0F-7EF1659C20AE" TemplateName="MPS#0" / >
< FeatureSiteTemplateAssociation Id="B21B090C-C796-4b0f-AC0F-7EF1659C20AE" TemplateName="MPS#1" / >
< FeatureSiteTemplateAssociation Id="B21B090C-C796-4b0f-AC0F-7EF1659C20AE" TemplateName="MPS#2" / >
< FeatureSiteTemplateAssociation Id="B21B090C-C796-4b0f-AC0F-7EF1659C20AE" TemplateName="MPS#3" / >
< FeatureSiteTemplateAssociation Id="B21B090C-C796-4b0f-AC0F-7EF1659C20AE" TemplateName="MPS#4" / >
< FeatureSiteTemplateAssociation Id="B21B090C-C796-4b0f-AC0F-7EF1659C20AE" TemplateName="WIKI#0" / >
< FeatureSiteTemplateAssociation Id="B21B090C-C796-4b0f-AC0F-7EF1659C20AE" TemplateName="BLOG#0" / >

...

Take note of the first child node - it defines a Feature (in this case, the BaseSiteFeatureTitle) to be included with the site identified by the TemplateName setting. Does this setting look familiar? It should, as it's the same as the STS (WSS Team Site) < Template > node in WEBTEMP.XML. The #0 after it refers to a specific < Configuration > child node. Since your new Site Definition needs to behave exactly as the STS definition does, you must create a < FeatureSiteTemplateAssociation > for each Feature that STS is associated with, like so:

< FeatureSiteTemplateAssociation Id="B21B090C-C796-4b0f-AC0F-7EF1659C20AE" TemplateName="CUSTOMSITE#0" / >

Simply go through BaseSiteStapling.xml and each time you see an ID associated with STS#0 add an entry for CUSTOMSITE. But wait, you're not done. You now have to do the same thing in the PremiumSiteStapling.xml file located in \12\Template\Features\PremiumSiteStapling folder and, if you want the included workflows, do the same in FeatureStapling.xml in \12\Template\Features\StapledWorkflows folder.

Perform another IISRESET and create a new Site Collection based on your custom Site Definition. Now, when you edit the site in SharePoint Designer, you will see all the right files in /_catalogs/masterpage, such as DefaultLayout.aspx, AdvancedSearchLayout.aspx, SearchMain.aspx, etc.

As an aside, you can mimic some of the Publishing functionality of the Portal Site Definitions by create your own Style and Images libraries, uploading your files, and referring to them from your customized master and layout pages by relative URL (such as ../../images/myhomepageimage.gif or ../../styles/custom.css). See this post for information on how to override CORE.CSS using this method.


kick it on SharePointKicks.com

Thursday, February 01, 2007

Overriding Default Stylesheets in SharePoint 2007

Heather Solomon posted a detailed explanation on her site regarding the inheritance of styles in MOSS; specifically, the various methods for overriding CORE.CSS in master pages and site definitions. After defining the various options, Heather recommends the following for applying custom styles:

My recommendation is to store styles in the master page itself in a set of STYLE tags. If your master page design has variations for assorted subsites, store the CSS differences in a file and reference it via the Master Page settings, or if you need CSS changes for a single page, store it in an HTML file and reference it in a hidden Content Editor Web Part.

I wasn't at all comfortable with this approach, not so much because there is anything wrong with it (there isn't and Heather should get an award for incurring the brain damage required to sort through it all), but mostly because I don't like the idea of SharePoint forcing a default style onto my customized pages, thereby making me jump through hoops to correct a deficiency that never should have been there in the first place. I thought we'd been through this enough with 2003 and the design team would have learned their lesson but apparently not.

So after playing around with a few alternatives, I went old school and found the solution. Instead of using one of the new < SharePoint:CssRegistration / > tags to register your override style in the header, simply place it in a classic ASP < link > tag in the same location, like so:

< link rel="stylesheet" type="text/css" href="../../Style Library/en-us/Core Styles/core_override.css" / >

This procedure will circumvent whatever the parser is doing in the background to throw CORE.CSS into the mix at all the wrong places. The beauty of it is that CORE.CSS is called before your override stylesheet so you can inherit all the default styles and only override the styles you need. Be sure that the relative path is correct for the site definition you are working with. An alternative would be to place your override into the same folder as CORE.CSS and use a fixed path, which would make working with different site definitions much easier, as each master page can point to its own override file (this can also be done programmatically).

UPDATE: As Shane points out in his comments on this post, using the alternate style setting in the site collection settings IS a reliable method for overriding CORE.CSS; however, there are some things you should consider if you are using this approach:

1) The alternate CSS setting is GLOBAl for the site collection. This means that all pages, including _layout pages, will inherit this style. That may work for one implementation and not another; you might want different styles for the Admin pages (my term for all the pages found in _layouts), content pages, or subsites.

2) The Alternate CSS setting applies to all subsites in the collection, making it more difficult to assign those styles programatically. If you want to mix and match styles in your subsites you will have to find a method to override both CORE.CSS AND the alternate style.

3) The alternate setting must be done AFTER the site is provisioned. This obviously won't work for custom site definitions. A better approach would be to put the style in the master page settings, the PlaceHolderAdditionalPageHead, or, as I have suggested, use a <> tag.

Saturday, January 20, 2007

SharePoint 2007 and the .NET 2.0 Object Data Source

One of the smartest SharePoint gurus I know is Sean Skinner. Lucky for me, he was guillable enough to be fooled into coming to work for my company, so now I get to take advantage of all his know-how on a daily basis. Like, for example, when one of our SmartForms apps blew up all over the place, and we couldnt' figure out what in the world was going on, Sean kept at it until he had the answer. From his blog:

You cannot have an Object Data Source running on MOSS and it have a parameter (insert, update or otherwise) with a type of 'object'. This appears to be the type assigned for GUIDs (database fields of type 'unique identifier'). When you do, as soon as I would bind the formview I would get a generic MOSS error page. You know the one, 'A web part is causing a problem....'By changing the type on the parameter to 'string' everything started working...


(BTW, when he refers to ASP:Table elements junking up otherwise working code inside of SharePoint, what he really means to say is "Eric screwed up my perfectly functional code by filling it up with server-side elements that we didn't need". Now you know the rest of the story...)

There'll be a whole lot more where that came from when we get all of our blogs moved over to the new MOSS site so stay tuned - and if you don't read Sean's blog already, you're missing out. Add it to the 'ol blogroll, pronto!

Tuesday, January 16, 2007

Tag, I'm It!

I was harboring secretive dreams that the recent spate of tagging would leave me unscathed but my hopes have been shattered. Friend and fellow powerblogger Heather Solomon got me at last. So what are five things that people don't know about me that aren't either a) embarrassing or b) still subject to a statute of limitations? How about these:

  • My primary intellectual hobby is ancient Egyptian history. I've read dozens of books on the subject, seen every documentary ever created, visited nearly every major museum with an Egyptian exhibit, and can even read and write some hieroglyphs. As an offshoot, I've also studied a tremendous amount of early Judaic and Christian history as well. If you value your sanity, don't ever get caught near the British Museum with me around or you'll end up losing an entire day of your life to my endless chattering about the proper pronunciation of Tutuanhkamun and why I think Zahi Hawass is an idiot. Unfortunately, I've never had an opportunity to visit Egypt in person but it's on my list of first things to do when I eventually take a vacation (yeah, right).
  • My favorite activity is training and hunting with my Labrador Retriever. If you're not an animal person, you just won't get this, but there is nothing more rewarding than the bond between human and dog when engaged in a singular activity. Cheyenne, my 100-pound black Lab, is an amazing creature - watching her do what she was bred to do is a wonder to my eyes. I spent two years learning about training hunting retrievers before I got her and I trained her myself from the time she was five weeks old. I took a chance and didn't buy her from a breeder (no reason to invest that kind of money if you're not sure of your own skills) but boy did I get lucky - she can hold her own against any of those pedigreed wondermutts you see on TV. One thing I've learned from her that has served me well is that a good dog doesn't need to be trained to work with a person - the person needs to be trained to work with the dog. The dog was born knowing what to do, it's us humans that get things all screwed up. Take that for what it's worth.
  • I'm part Scottish and part Native American (Mescalero Apache). My mother's family is Scottish down to their kilts. My uncle used to be one of the premier bagpipe instructors in the country and my cousin has played the pipes live for Rod Stewart on several occasions. Our line goes back to one of the oldest highland clans, the Atholl Murray's, and one of our ancestors came over on the Mayflower. My paternal grandmother is full-blooded Apache Indian. Unfortunately, all her birth records were lost in a fire years ago so we can't trace back our heritage on that side. And yes, I can drink me some whisky, in case you were wondering :-)
  • I play the harmonica. Or, rather, I did, then I gave it up, then I picked it up again, and now I can barely play the thing anymore. I keep threatening to take it up again but the rolled eyes around my house indicate that I may need some serious refresher courses before I'm allowed to blow any riffs around the 'ol campfire.
  • I used to sell floorcovering. At one point when I was living in California I got burned out on the technology business and went to work selling carpets, wood floors and tile. I did pretty well and actually had a good niche doing custom wood floors and high-end commercial projects. I even learned how to tear it up, install it, do finish work, everything. About as far from high-tech as you can get but at the time that was the whole point. It was fun but I don't think I was cut out for it - I kept finding excuses to play with company's computers and not rearrange my samples on the sales floor. Ah well, once a geek, always a geek!

So there you have it - more than you ever wanted to know about this humble SharePointer. Everyone on my list has already been tagged, so I guess I'm a 'dead end', so to speak. Hey, the chain had to end somewhere, didn't it???

UPDATE: Turns out there are a couple of people who have been flying under the tag radar and need a good one slapped on 'em:

Sean Skinner
Nick Swan

You're it!!!

Tuesday, January 02, 2007

Happy New Year!

To all my readers around the world, I want to wish you a safe and prosperous New Year.

First, I'd like to thank everyone who reads and contributes to this blog. I started blogging in 2005 to share my thoughts with other SharePointers and I never dreamed that I'd be collaborating with people all over the world would. Last year more than 23,000 visitors read this blog and more than 60,000 pageviews were generated for readers in more than 20 countries. Sure, Bil and Jan and AC get more traffic but it's not bad for a country boy from Texas.

Second, my apologies to those very same readers for not posting more often in 2006. Business exploded this last year, leaving me with little time to sleep or eat, much less post regularly. I plan to correct that this year by setting (and sticking to) a regular blogging schedule.

Finally, the new year brings new changes. The eGroup started as a one-man SharePoint consultancy but has now grown by leaps and bounds, with some great new team members coming on board, new offices opening in the UK, and lots of other positive developments. To reflect these changes, we'll be changing our name and launching a new site soon (built on MOSS, of course). With more exposure comes more responsibility, so we'll be releasing more products, tools and utilities throughout the year and participating in events and conferencese throughout the US and Europe (I'll finally get a chance to meet many of you face to face for the first time - hoorah!).

As part of these changes, this blog will be moving to our MOSS web farm and off of Blogger. Not that Blogger hasn't done its job but with the new blog templates in MOSS there's just no reason not to switch. The good news is that all of our consultants and developers will be blogging on the new site so there will be lots of fresh new ideas and solutions. Links to all the new blogs and sites will be posted soon.

I look forward to a very exciting 2007.

Happy SharePointing!!!

Monday, November 27, 2006

Looking For A Few Good SharePointers

It's that time of year again - no, I'm not talking about jolly 'ol Saint Nick, annoying crowds at the mall or an XBox in your stocking (hint, hint), this is even better - The eGroup is hiring! If you've got SharePoint development experience and you're itching to work with a dynamic team of fellow SharePoint-crazy codeslingers, mosey on over to our job postings and see if you fit the bill. No, you won't a free Tesla Roadster and you'll have to bring your own Aeron, but you will get to work on exciting client projects using the latest and greatest Microsoft technologies. Give yourself a Christmas present and tell the boss man you're movin' on up!

UPDATE: UK readers take note - we'll be hiring on your side of the pond in the first quarter of '07. We'll be looking for both experienced and junior SharePoint developers so send in your CV if you'll be in the market for a new gig after the first of the year. In fact, if you're in and about London, drop by the SharePoint UK User Group Meet Up on December 14th (you are a memeber, aren't you?) and introduce yourself (I'll be the only 6'5" Texan in the pub - pretty easy bloke to pick out of a crowd).

Monday, October 23, 2006

SPSiteDataQuery vs. GetListItems

Mart Muller over at TamTam posted his thoughts about using the new SPSiteDataQuery object in MOSS 2007 to retrieve items in a document library without tripping over the annoying folder limitations of the much-maligned SPQuery class. This is handy method for getting list data via the object model but it also has some limitations and 'gotchas' to be aware of.

First, when retrieving list data, anecdotal tests have shown (and our experience has proven this to be absolutely true) that the object model is best suited for working with smaller data sets within web parts or controls in small to medium traffic environments (~10,000 users). Why is this? Nobody seems to know for sure but I suspect that it has to do with the overhead related to repeatedly calling the core DLL's that are also performing a number of other concurrent tasks (but I could very well be wrong; the cause may be up for debate but the results speak for themselves).

Second, as Maurice Prather and Bil Simser have pointed out here, here and here, all those SPSite and SPWeb objects you're throwing around in your code don't dispose of themselves - you have to handle that yourself (you are disposing of your garbage, aren't you?). Those little guys riding round on the back of the Garbage Collector truck never see those objects so they don't throw 'em on the rubbish pile - leave a few thousand of those things open and your application pool will come to a screeching halt.

Third, you have to keep a careful eye on that ViewFields element (and don't forget to write your query correctly). A blank value will return all the fields that the records have in common but not any fields that have blank or null values - these are omitted from the results. This is important when you're looking for a particular field only to discover it's not there at all - crash goes your code. Pass in a null value and you get the default view (such as AllItems.aspx) which may not contain any of the fields you're looking for. You have to specify ALL of the fields that you want to appear in the results. And, just to keep you on your toes, make sure to use the DisplayName value of the column in each < FieldRef > node and not the Name value (they are often quite different, especially in custom lists).

Finally, remember that object model methods of this type are always subject to the annoying but ever-present impersonation issue. Call SPSiteDataQuery in the wrong user context and you won't get very far. RevertToSelf, anyone?

Personally, I prefer to use the web services GetListItems() method to get items from a list because a) it's faster (I know, you don't believe me, but it's true - someone somewhere did a performance comparison once but I can't seem to find it again. UPDATE: Found it here but there aren't any hard metrics in the post. UPDATE II: Scroll to the bottom of this post for some very basic metrics), b) I have more granular control over user credentials (I can use an admin account to get the items then check the user perms to verify the access level - no impersonation required), c) the data is returned as an XMLNode object, and d) there's no garbage to worry about - once the TCP connection is closed the memory is released. Most importantly, the web services scale well, especially in shared services environments where you may have one portal context accessing list data from another portal context. That being said, I will probably use the SPSiteDataQuery object in one-off web parts where scalability and performance are not an issue because the code is short and sweet - which is an advantage unto itself, now isn't it?

Thursday, October 19, 2006

New Article on Custom Master Pages

I get a lot of questions from readers and clients regarding deployment of custom master pages in MOSS 2007. There are several ways to tackle this problem and here's a very good place to start - Heather Solomon's new article on How to Create and Store Master Pages on the Server for Use with Site Collections. Heather is one of my all-time favorite MVP's (I swear someday I'm not going to be neck-deep in projects during a SharePoint conference and we'll actually meet in person) and if you're not reading her blog on a regular basis then you're missing out. Go check it out and get those custom master pages going.

Wednesday, October 11, 2006

To < Query > Or Not To < Query >, That Is The CAML Question

If you do any development using SharePoint's web services you've undoubtedly run across the evil CAML beast rearing it's ugly head to devour your nicely structured markup. For instance, if you invoke GetListItems() to retrieve the column values of each item in a list, you have the option of passing in a CAML query to return specific records or a blank value to get the whole enchilada. The SDK is quite helpful, as it documents how this specific query should look. If, for example, you want a particular record with the title "Yellow", provide the following CAML:

<Query><Where><Eq><FieldRef name="Title"><Value Type="Text">Yellow</Value></Eq></Where></Query>

Simple, no? Well, not quite so simple. Try as you might, this query will never return just those items whose Title column is equal to "Yellow". Instead, the web service will happily ignore your fancy little CAML fragment and give you all the records in the list. Alas, no amount of cursing, head beating, keyboard throwing or foot stomping will make it otherwise. I assure you, I have tried all of those methods, and many more, to no avail. What DOES work is simply removing the <Query> and </Query> tags, like so:

<Where><Eq><FieldRef name="Title"><Value Type="Text">Yellow</Value></Eq></Where>

What's that you say? That's not how the SDK says it should be done? You spent hours searching the newsgroups and nobody once mentioned this little bit of CAML trickery? I feel your pain, my friend, believe me, I do. Were it not for my innate stubbornness and determination to beat SharePoint at it's own game, I would have given up on this vexing problem many moons ago. What can I tell you - CAML is a mysterious creature and we know not it's wild and wily ways. Now go ye forth and slay that noxious Query fiend - or at least stab at it until the next time it bites you on the rear!