Since moving to working with SharePoint and in the Microsoft arena, I seem to keep coming across this phrase ‘Best Practices’. It bugs me – I’ve been working almost exclusively with SharePoint 2007 since it was out in Beta 1, and you know what? I still have no idea what best practice is. Continue reading
Knowing when to dispose of SPWeb or SPSite objects is confusing as hell. Well, Roger Lamb has an excellent page showing patterns that can leak memory, and how to avoid them. This should be mandatory reading for SharePoint devs. (Previously mentioned here – but this is a better link)
Edit: As Steven Van de Craen points out, you can use the Properties collection on the Root folder for the List. Neat, didn’t think of that.
I like property bags in things. Sure, they’re open to abuse, but they give an easy way of storing a little extra data, and as a developer, I find that very useful.
For those of you who are wondering what a property bag is, well, it’s a collection on a object where a programmer can just store stuff. E.g.
SPWeb site = properties.Feature.Parent as SPWeb;
site.Properties["Kumquat"] = "True";
Now, clearly the SPWeb object in SharePoint’s API doesn’t have a property called Kumquat; we’re defining a new one, and storing a string. In fact, string objects is all you can store.
Anyway, SPListItems and SPWeb both have property bags, but SPList and SPSite do not. Which is a little annoying, as I want to store some data at the list level, dammit. And I hadn’t realised this ommission until now…
Thoughts on Steven’s point – it’s a good one, and using the root folder would work. Naturally, this means that you’re storing the properties in the SPFolder object, but each list should have one of those, I think. It’s a bit of a pain as, if you’re using the Web Services then I’m sure that getting that root folder will take another call – but as I’ve not validated that the properties are available via the web services, then that might be a moot point anyway.
A couple of months ago I was making some calls to the SharePoint Lists Web Service, and I found that I was getting the same item back multiple times. This puzzled me – I mean, it was clearly by design, but why would anyone want a copy of the item for each value selected in a multiple-selection lookup?
It hit me last weekend (like a bolt from the blue) – you could use this to support Group By clauses on queries on a list. Yes, I know, SharePoint itself doesn’t support this functionality, but you could use the behaviour that I’d seen to support this. It’s the only explanation I’ve found that makes sense.
Now, can you turn off this behaviour, so you only get one item. That would be a lot more useful for what I was trying to do, although I now get why you might want that behaviour. Well, I don’t see a query option for it in the documentation, and cracking the service open in Lutz Reflector doesn’t show an option for it either.
I guess we’ll just have to accept the GetListItems command in the Web service API supporting Group By functionality, while SharePoint’s user interface itself does not. It’s a bit weird though that there isn’t an option I can find to turn it off though, and the Object Model behaves quite differently – it only returns one ListItem, and is unaffected by the multi-select lookup.
Previously, I’ve detailed my attempts to show a query string parameter in a page. This should be a simple enough to do as inline code, but as my previous attempts recorded, when I tried:
<%= Request.QueryString.ToString() %>
I got the error “code blocks are not allowed in this file”. This makes sense, as otherwise anyone with SharePoint Designer could put arbitrary code into a page and get it to run. Clearly, as this would let business users enter code, this would not be very secure.
Now, you can turn off this security restriction using Page Parser Paths, but this reduces the security of the system – again, anyone with SharePoint Designer could put code in without review/authorisation. Again, less than ideal.
Well, one of the things I learnt last week was that uncustomised pages (or ‘ghosted pages‘ for the oldies) will run inline code. Fantastic! After all, we’re going to want to package up our code for deployment from Development to Testing and Production systems, right? (Well, you should be, dammit!)
For those of you who don’t know, uncustomised pages are ones that are stored on the server’s hard drive, rather than in the database. To get onto the hard drive, someone has to install them, which means that someone has to review and approve the code. With SharePoint designer, this isn’t the case, and SharePoint Designer can only create pages that are Customized (or Ghosted), and so exist only in the database.
So overall, the process would probably become:
- On a development system use PageParserPaths to enable inline code. As this is a dev system, security is less of an issue, and business users won’t be making changes.
- Develop your pages that use inline code. You can do this in SharePoint Designer.
- When the pages are complete, copy them out and package into a feature. Make sure that your page that you’ve written in installed Ghosted – still the terminology they use in features.
- Install and activate the feature. As your page is now uncustomised (or ‘ghosted’), it will now run inline code without PageParserPaths being configured.
That’s a pretty tidy developer story!
Last week I was away training in London – hence the last of posts on the tail of last week. I was at ‘Xpertise’ in London, although the training was being provided by Ruth Jennaway on behalf of Ted Pattison Group. The course itself was SPT 401 – Inside SharePoint Products and Technologies, though I can’t find this on their website. Continue reading
So, recently I was doing some work with SharePoint Web Services, getting possible values for Lookup fields. One of the functions I was using was GetListItems(), to get the values that the lookup field could take.
The method’s signature is:
Lists.GetListItems( [List], [ViewName], [Query], [ViewFields], [RowLimit], [QueryOptions], [WebID]);
I’m not going to talk about most of these parameters – you can read about them here. For my query, most of these parameters were Null (i.e. they were unused). However, the [List] parameter interested me. It’s the ‘Name’ of the list, though I prefer using a GUID (a unique ID) for the list.
The lookup column I was using was defined in a different site to the one where I was making the GetListItems call. I’d pass the GUID, and get the correct values back. My call actually was:
XmlNode resultNode = _lists.GetListItems( listGuid, null, null, viewFields, null, null, null);
So, this query was finding the correct list elsewhere in the site collection based only on the GUID. Interesting – I’m not passing a WebID, and the list is outside the site I’m currently using the web services of. This set me thinking – clearly the call was selecting by list GUID against a table of all ListItems in the site collection.
I was a little surprised – then it hit me – the Content Query Web Part also does that. But how?
Well, a bit of searching later and I found the SPSiteDataQuery object. The object is used for queries against multiple lists in multiple sites. You can specify the types of list to query, values to filter, order by, display, etc.. I’m pretty sure that this is what the Content Query Web Part uses.
Neat! Now I just need to find a reason to use it!
Twospeakers at the user group meeting last night. The first session was an eye opener for me, one of those ‘thoughts crystalising’ moments. Continue reading
You should dispose of SharePoint objects like SPWeb and SPSite. Gotta admit, I hadn’t realised they were disposable.
Some weird behaviour with SharePoint column types, and the data you get by looking at the SPListItem.properties hash.
So, I’ve got a document library, and I’ve added 3 extra columns to it. For simplicity, I shall call them ‘Text’, ‘Number’ and ‘CheckBox’. I filled in some data for them – a number in the Text field, the same number in the number field, and I check the checkbox for all of the items. I end up with a list looking like below…
So, for now, let’s ignore the fact that the value for some of the longer numbers has been rounded in one of the fields – and not ask why MOSS didn’t just complain that the numbers were too big. Instead, let’s ask what the column types being used are… Continue reading