Getting field values of an SPListItem returned from an SPQuery – watch out!

16 02 2010

I have seen and read about this gotcha before but even so I still fell for it today and it took for a couple of hours to figure out so I’ve decided to blog about it.

If you are working with SharePoint items in code which you have returned using a CAML query then you should always populate the SPQuery instance’s ViewFields property. You must include in here all the fields for which you might need to get the value of later. Failure to do this will mean the returned SPListItem instances might not contain the data for certain fields and will throw an exception (usually ‘Value was not within the expected range’).

The ViewFields property is set like this:


    <fieldref name="Title" /><fieldref name="Created" /><fieldref name="ID" />

    

You can then access a fields value on an SPListItem instance using the normal code:


    SPListItem item = list.GetItemById(1);

    string Title = item["Title"].ToString();

    

Hope this helps!!

Advertisements




Debugging SharePoint code when using PowerShell

10 02 2010

Note to self and anyone else who is interested –

When trying to debug code – a FeatureReceiver in my case with Visual Studio when you are using PowerShell to actually kick off the event you need to ‘powershell.exe’ process in addition to the normal w3wp worker processes. If you don’t do this then your breakpoints won’t get hit it seems.

Hope this helps someone!





SharePoint, AJAX UpdatePanel and SPWebPartManager woes

26 01 2010

If you are having trouble getting your AJAX UpdatePanel to update properly in a SharePoint page or Web Part then you have come to the right place. You may already be aware that to get an UpdatePanel working in SharePoint you need to add a an additional function to your code that alters the _spFormOnSubmitWrapper and the _spSuppressFormOnSubmitWrapper. See here for an example –

http://petesullivan.wordpress.com/2008/06/13/ajax-update-panels-and-sharepoint/

However!! If you are using a custom Master Page then watch out because there is another gotcha!

It seems that if the SPWebPartManager tag appears before the Form tag in your master page then your updatepanel will not update properly and most likely won’t display any content. This should be changed so the SPWebPartManager tag appears underneath the form tag, see below for an example –

Incorrect

<WebPartPages:SPWebPartManager ID="SPWebPartManager1" runat="server"/>   
<form id="Form1" runat="server" onsubmit="return _spFormOnSubmitWrapper();">

Correct

<form id="Form1" runat="server" onsubmit="return _spFormOnSubmitWrapper();">
<WebPartPages:SPWebPartManager ID="SPWebPartManager1" runat="server"/>

Hope this helps! 🙂





Creating Custom SharePoint Web Part Connections

25 01 2010

I created my first web part connection the other day and was surprised at how easy and effective it was. I thought I would walk through the process that is required to connect two custom web parts together.

In this brief tutorial I am not going to cover how to create a web part or how to deploy one. I will assume that you (the reader) already knows how to do this. All code in this tutorial will be written in C#.

1. To begin create yourself two web parts – one of these will be the ‘Provider’ and the other the ‘Consumer’. You can create these however you like either using the VseWSS extensions or perhaps in an empty class library project.

2. Create an interface similar to the one below –

 public interface IExampleProvider
 {
        String TestParam { get; }
  
 }

Inside this interface you should define any parameters that you wish to send to your ‘Consumer’ web part.

3. In your Provider web part ensure that it implements the interface you have just created –

 public class ProviderWebPart: WebPart, IGovernanceProvider
 {
 }

4. Next create a property that returns the interface and decorate it with the  ConnectionProvider attribute. The parameters of  are the display name and the real name (ID) of the connection.

 [ConnectionProvider(&quot;Test Parameter&quot;,&quot;ExampleID&quot;, AllowsMultipleConnections=true)]
 public IExampleProvider GetExampleProvider()
 {
    return this;
 }

5. Finally for the Provider web part you need to ensure that the parameter property from your interface is implemented –

protected string _TestParam = &quot;&quot;; 
public string TestParam 
{
 get { return _TestParam; } 
}

6. Now its time to setup the Consumer web part, in your consumer web part class define a method that will accept the interface as a parameter and decorate it with the ConnectionConsumer attribute.

private IExampleProvider exampleProvider;
[ConnectionConsumer(&quot;Site URL&quot;)]
public void RegisterProvider(IExampleProvider provider)
{
   this.exampleProvider = provider;
}

7. You can now retrieve the value/values that have been sent to the consumer web part by calling the properties of the exampleProvider. Note you should check if a connection has been made first by seeing if the exampleProvider is null.

string myParam = this.exampleProvider.TestParam;

8. Deploy your two web parts by whatever method you wish, when you add the web parts to the page and click the ‘edit’ dropdown you should see a new menu option called ‘Connections’. The menu will appear on both the provider and consumer web parts but you only need to configure one.

Consumer Web Part:

image

Provider Web Part:

image

9. You are finished!

I hope you enjoyed this brief tutorial into web part connections, if you have any questions then feel free to leave a comment!

Hope this helps 🙂





Programmatically update InfoPath form Content Type to open in browser

11 12 2009

If you are deploying an InfoPath form to your site as a feature then it is highly likely your form will be installed as a content type. By default however the form will try to open in the InfoPath client if there is one installed on the machine.

You could of course go into the list settings and change this so that new instances open in the browser but this is pain if you are trying to create an automated install/deploy process.

So how can I do this programmatically I hear you ask??

Well it turns out that the SPContentType class has a property called RequireClientRenderingOnNew. This is a boolean value which is by default set to ‘true’.

See the below code snippet on how to change this –

   1: SPContentType cType = web.ContentTypes["My ContentType"];

   2: cType.RequireClientRenderingOnNew = false;

   3: //Update the content type

   4: cType.Update();

The best place to perform this change would probably be in a ‘featurereceiver’.

Hope this helps 🙂

UDH7UPSSP9QQ





SPListitem.File.Versions – System.Argument.Exception

28 10 2009

I was writing some code yesterday to loop through the list items in a SharePoint list and then loop through each version of the SPListItem’s underlying file.

Here is the code I was using –

using (SPSite site = new SPSite("http://theserver/"))
           {
               using (SPWeb web = site.OpenWeb())
               {
                   SPList list = web.Lists["The List"];
                   SPView view = list.Views[new Guid("D9E7BDDC-4C77-4386-BA0E-A786D58EE199")];

                   SPListItemCollection itemCol = list.GetItems(view);

                   foreach (SPListItem item in itemCol)
                   {
                       foreach (SPFileVersion version in item.File.Versions)
                       {
                           string url = version.Url;
                       }

                   }
               }
           }

When the code hit the ‘item.File.Versions’ collection it threw a System.Argument.Exception. This really stumped me and I couldn’t figure out at all while the collection was throwing this exception.

After a lot of researching I found this blog post –

http://www.mtelligent.com/journal/2007/10/17/the-insanity-of-getting-versions-of-a-multilinetext-box-set-.html

In this post, David talks about getting the same exception when he is trying to access the list item’s file versions. If you scroll down and look at the comments you you will see that this only seems to be a problem if you are getting the SPListItem as the result of an SPQuery (in my case the spquery is actually an SPView).

This is most likely because getting the item using an SPQuery returns the list item with a minimum amount of data, therefore the versions are not accessible.

The solution here is to create another instance of the SPListItem by using the GetItemById() method which will return all the properties for the list item. This way the SPListItem.File.Versions collection will be accessible and we can iterate through it.

See the correct code –

using (SPSite site = new SPSite("http://theserver/"))
           {
               using (SPWeb web = site.OpenWeb())
               {
                   SPList list = web.Lists["The List"];
                   SPView view = list.Views[new Guid("D9E7BDDC-4C77-4386-BA0E-A786D58EE199")];

                   SPListItemCollection itemCol = list.GetItems(view);

                   foreach (SPListItem item in itemCol)
                   {

//Get a reference to the item again by the ID

SPListItem theItem = list.GetItemById(item.ID);

//The versions collection should now be populated (if versions are available) and no exception should be thrown

                       foreach (SPFileVersion version in theItem.File.Versions)
                       {
                           string url = version.Url;
                       }

                   }
               }
           }

Hope this helps someone! 🙂





SPBuiltInFieldId – Very useful

22 10 2009

If you ever need to get the GUID of a built in SharePoint field such as ‘IssueStatus’ (from the standard ‘Issue Tracking’ list) for example then you can use the SPBuiltInFieldId class.

This class contains a number of GUID objects for each type of built in SharePoint field.

To use it simply use the following code:

Guid issueStatus = SPBuiltInFieldId.IssueStatus;

I found this very useful, hope it helps some of you!