Getting levels of the SharePoint Heirarchy and their Exceptions

Something that I have to do time and again is get some element of SharePoint’s heirarchy, such as a site collection, site, list or item. This is pretty typical – that’s why we all use USING to ensure proper disposal of SPSites and SPWebs, right? But what happens if the thing you’re after isn’t there? What exception get’s thrown? Well, this should be pretty clear:

try
{
    //FileNotFoundException if doesn't exist
    using (SPSite site = new SPSite(siteGuid))
    {
        //FileNotFoundException if doesn't exist
        using (SPWeb web = site.OpenWeb(webGuid))
        {
            //SPException if doesn't exist
            SPList list = web.Lists[listGuid];

            //ArgumentException if doesn't exist
            SPListItem item = list.GetItemByUniqueId(itemGuid);
        }
    }
}
catch (System.IO.FileNotFoundException fileEx2)
{
    // Site or Site Collection Not Found
}
catch (SPException spEx2)
{
    // List not found
}
catch (ArgumentException argEx2)
{
    // Item not found
}

Hopefully that might prove useful to someone – and a good reminder for me.

Getting levels of the SharePoint Heirarchy and their Exceptions

Hide Column type from Lists

So, you’ve created a new custom Field (or column) type, but you don’t want it to be available to add directly to Lists and Libraries – that is, you want to force users to create columns as Site Columns, and add those to the list. Conversely, maybe you want to prevent a column being created as a Site column, and only available to add directly to lists (though I can’t thinik why).

Well, it turns out that that is possible. In the CAML defining your field in fldtypes_???.xml, you can have something like the following:

<FieldTypes>
    <FieldType>
        <Field Name="TypeName">MyCustomField</Field>
        <Field Name="ParentType">MultiChoice</Field>
        <Field Name="TypeDisplayName">My Custom Field</Field>
        <Field Name="ShowOnColumnTemplateCreate">TRUE</Field>
        <Field Name="ShowOnListCreate">FALSE</Field>
        <Field Name="ShowOnDocumentLibraryCreate">FALSE</Field>
        <Field Name="ShowOnSurveyCreate">FALSE</Field>
        <Field Name="Sortable">FALSE</Field>
        <Field Name="Filterable">TRUE</Field>
        <Field Name="ShowInEditForm">FALSE</Field>
        <Field Name="UserCreatable">TRUE</Field>

ShowOnColumnTemplateCreate controls visibility as a Site Column type. The other ‘Show On X’ values control visibility as a List Column Type for different types of List. You could, therefore, have a Column Type that can only be used on, say, Document Libraries. Hope that helps.

Hide Column type from Lists

Get the URL of a list

This is a seemingly simple task – given a List or Library in SharePoint, how do I get it’s URL? The difficulty here is that a List has multiple URLs – one for each View on the list. We can get those URLs, but sometimes you really just want the URL to the list, without the /forms/something.aspx bit too.

For example, you might want http://server/siteCollection/site/lists/somelist . If you entered this URL, you’d be taken to the default View for the list, so you don’t really need the extra /forms/… bit to identify the list – that’s all about identifying the view.

Sadly, though, there is no SPList.Url property or equivalent on the SPList object. So, how can I get a list’s URL? Continue reading “Get the URL of a list”

Get the URL of a list

Rendering List Fields from other sites

I had a requirement recently to display the fields of a SharePoint item in another SharePoint site. Now, you can do this with things like the Content Query Web Part, or Data View Web Part, but I was doing a few other things, and specifically, I needed to pull the fields to display from a particular View on the list.

This turned out to be quite an interesting problem. All fields use a subclass of BaseFieldControl, and this is what renders the field – so it appeared to be fairly straight forward. As always, though, there was a little kink to it – you need an SPContext for the site the item comes from, and you need to use this as the contexts for the SPField‘s rendering control:

SPContext ctx = SPContext.GetContext(HttpContext.Current, item.ID, relatedList.ID, relatedWeb);

SPView relatedView = list.DefaultView;

foreach (string vf in relatedView.ViewFields)
{
    SPField fld = relatedList.Fields.GetFieldByInternalName(vf);

    HtmlGenericControl titleLabel = new HtmlGenericControl("H3");
    titleLabel.InnerText = fld.Title;
    this.Controls.Add( titleLabel );

    BaseFieldControl ctl = fld.FieldRenderingControl;
    ctl.ControlMode = SPControlMode.Display;
    ctl.ListId = relatedList.ID;
    ctl.ItemId = item.ID;
    ctl.RenderContext = ctx;
    ctl.ItemContext = ctx;
    ctl.FieldName = fld.Title;
    ctl.ID = Guid.NewGuid().ToString();

    this.Controls.Add( ctl );
}

Groovy!

Rendering List Fields from other sites

Getting Absolute URLs in SharePoint

This is a bit of a reminder for myself, but quite a lot of the URLs you deal with in SharePoint development are relative – that is, something like an SPList.DefaultViewURL might be:

/sites/web/lists/list/allitems.aspx

That’s fine … but sometimes you need a full absolute URL. For example, you might be sending out an email with a hyperlink in it – a relative URL ain’t going to cut it.

Fortunately, there is a very useful function – SPSite.MakeFullUrl() :

Returns the full URL for the specified server-relative URL.

That’s great – but it raises some questions. What about Alternate Access Maps? What URL would be returned? Well, predictably, the URL used in the SPSite Constructor in the first place. Mostly, they either accept a URL (which defines a zone), or they accept a GUID and an SPUrlZone value. There is a constructor that just accepts a GUID – which will then use the default zone. Similarly, the constructor accepting a GUID and SPUserToken also uses the Default Zone.

(If you open it up in reflector, you can see it just calling a private constructor passing the SPUrlZone.Default value).

Getting Absolute URLs in SharePoint

"To save to the server, correct the invalid or missing required properties"

I’ve been working on a custom field for, well, a while now, and after making some changes I started to get the error “To save to the server, correct the invalid or missing required properties” when trying to edit a document and save the changes back in Word 2007. This was a little strange, as I’d already sorted out hiding the custom field from the document information panel, and things had been working fine since then.

New documents seemed to be alright, but the older ones weren’t. So, maybe the problems were all the old documents, rather than my field.

Eventually, I came across this knowledgebase article – so I “inspected” the document, removed any of it’s custom data, and resaved it – and it worked fine.

What I think happened here was, I was testing different settings for Content Approval and Versioning on my document libraries. I think the troublesome documents were created when one of those was set to be ‘on’, and I subsequently turned it ‘off’. This meant that the document actually had extra data that referred to a column that no longer existed (I think) – which probably means this is related to Content Approval.

But I’d be curious if anyone else has managed to cause this error, and how they did so.

"To save to the server, correct the invalid or missing required properties"

Inconvenient GetCustomProperty and SetCustomProperty

So, I’m working on a custom field definition for SharePoint. My field has a few custom properties that you need to fill in when you create it. However, after creation, those fields were empty – they were simply never set. You could then update them, and that worked fine, but creation was broken.

The code I’d inherited was trying to solve this problem (it’s a known issue) this way – which is a bit ugly. It also holds memory for the Dictionary of values that, as far as I could see, was only being freed on IISReset. Yuck. And it didn’t work in our code, despite matching the example in that thread quite closely.

Fortunately, I came across a neat post on Gunnar Peipman’s blog – Temporary Solution for GetCustomProperty an SetCustomProperty Errors. I don’t like using reflection to invoke the methods I need to use, but at least it’s a solution, even if not ideal. And it works!

Please go to Gunnar’s post – but just in case his blog goes down, I’m going to shamelessly plagiarise his code below…

Thanks Gunnar! Continue reading “Inconvenient GetCustomProperty and SetCustomProperty”

Inconvenient GetCustomProperty and SetCustomProperty

Registering EventHandlers against ContentTypes

In SharePoint, Event Handlers (or Event Receivers – whichever terminology, a child of SPItemEventReceiver) can be registered against lists/libraries. You can do this through an SPWeb (site) scoped feature, declaratively or programmatically with an SPEventReceiverDefinition.

Unfortunately, you can’t declaratively register event receivers at the SPSite (Site collection) level – which would be fantastic – just turn on the feature and across all your site collection lists/libraries of a give type would get additional event receivers. Personally, I think this may be a bug; I don’t see why this shouldn’t work at the SPSite level.

Anyway, there is still another option – we could register our event against a particular Content Type. This is a less often used approach, which raises two questions – how do you do it, and what happens to child Content Types? Continue reading “Registering EventHandlers against ContentTypes”

Registering EventHandlers against ContentTypes

Bloody Wikis in SharePoint 2007

The other day I blogged about how weird ‘Blog Posts’ are. Well, I’ve also been looking at Wiki pages…

So, first off, as a reminder to myself, Wiki libraries are defined in the ‘WebPageLibrary’ feature. Took a while to track that down.

Second off, calling the SPListItem.Title for a Wiki pages causes an ArgumentException. (Waldek Mastykarz has written about this). Kind of makes sense – the wiki item doesn’t have a title – but I’d prefer it returned the filename (without extension) instead. That would seem a more useful compromise.

Bloody Wikis in SharePoint 2007

Weird ContentType of Blog Posts

Okay, this is weird.

I’m trying to do something with various types of item, including Blog Posts, in SharePoint. Naturally, I’m getting the SPListItem for them, and then the SPListItem.ContentType, so I can check what kind of item is it. The weird thing is, if I try to get a Blog Post, the SPListItem.ContentType is NULL. Continue reading “Weird ContentType of Blog Posts”

Weird ContentType of Blog Posts