| Subcribe via RSS

Create SPFieldLookup programatically

Februar 21st, 2009 | 5 Comments | Posted in .NET, SharePoint

There aren’t many posts describing how to add a SPFieldLookup column to a list programatically. Here’s how I do it:

I have a list named “MyList” and I have a list named “MyLookupList”. I want to create a lookup column within “MyList” looking up values from “MyLookupList”.

SPList myList = web.Lists["MyList"];
SPList myLookupList = web.Lists["MyLookupList"];
 
myList.Fields.AddLookup("Lookup", myLookupList.ID, false);
SPFieldLookup fieldLookup = myList.Fields["Lookup"] as SPFieldLookup;
// Display Title Column in lookup field 
// (this is shown by default but this way you can change it)
fieldLookup.LookupField = 
  myLookupList.Fields[SPBuiltInFieldId.Title].InternalName;
fieldLookup.Update();
Tags:

Simplify reading and writing field values of type SPFieldUser, SPFieldUrl and SPFieldLookup using extension methods

Februar 8th, 2009 | 11 Comments | Posted in .NET, SharePoint

To read or write values to fields of type SPFieldUser or SPFielLookup is an annoying task because you have to create field value objects bevore you can write your values into a field. The following post descripes how you can encapsulate those tasks to extension methods and slim your code to make it more readable.

SPFieldUser

The following code displays a couple of extension methods extending the SPListItem class for simple reading and writing access to fields of type SPFieldUser.

using System;
using System.Collections.Generic;
using Microsoft.SharePoint;
 
namespace ExtensionMethods
{
    public static class SPListItemExtensions
    {
        /// <summary>
        /// Returns the login name of an User-Field.
        /// </summary>
        public static string GetFieldValueUserLogin(this SPListItem item, 
          string fieldName)
        {
            if (item != null)
            {
                SPFieldUserValue userValue = 
                  new SPFieldUserValue(
                    item.Web, item[fieldName] as string);
                return userValue.User.LoginName;
            }
            else
            {
                return string.Empty;
            }
        }
 
        /// <summary>
        /// Sets the value of a User-Field to a login name.
        /// </summary>
        public static void SetFieldValueUser(this SPListItem item, 
          string fieldName, string loginName)
        {
            if (item != null)
            {
                item[fieldName] = item.Web.EnsureUser(loginName);
            }
        }
 
        /// <summary>
        /// Sets the value of a User-Field to an SPPrincipal 
        /// (SPGroup or SPUser).
        /// </summary>
        public static void SetFieldValueUser(this SPListItem item, 
          string fieldName, SPPrincipal principal)
        {
            if (item != null)
            {
                item[fieldName] = principal;
            }
        }
 
        public static void SetFieldValueUser(this SPListItem item, 
          string fieldName, IEnumerable<SPPrincipal> principals)
        {
            if (item != null)
            {
                SPFieldUserValueCollection fieldValues = 
                  new SPFieldUserValueCollection();
 
                foreach (SPPrincipal principal in principals)
                {
                    fieldValues.Add(
                      new SPFieldUserValue(
                        item.Web, principal.ID, principal.Name));
                }
                item[fieldName] = fieldValues;
            }
        }
 
        /// <summary>
        /// Sets the value of a multivalue User-Field to 
        /// a list of user names.
        /// </summary>
        public static void SetFieldValueUser(this SPListItem item, 
          string fieldName, IEnumerable<string> loginNames)
        {
            if (item != null)
            {
                SPFieldUserValueCollection fieldValues = 
                  new SPFieldUserValueCollection();
 
                foreach (string loginName in loginNames)
                {
                    SPUser user = item.Web.EnsureUser(loginName);
                    fieldValues.Add(
                      new SPFieldUserValue(
                        item.Web, user.ID, user.Name));
                }
 
                item[fieldName] = fieldValues;
            }
        }
    }
}

The following lines of code demonstrate how these extension methods can be used.

using ExtensionMethods;
 
SPList list = web.Lists["MyList"];
SPListItem item = list.Items[0];
 
// Get a user login of a SPFieldUser field
string userLogin = item.GetFieldValueUserLogin("Author");
 
// Set a SPFieldUser field to a user using the login
item.SetFieldValueUser("Person", "alexander.bruett");
 
// Set a SPFieldUser field that allows multiple values to a list of users
string[] persons = { "alexander.bruett", "paul.panzer" };
item.SetFieldValueUser("Mehrere Personen", persons);
 
// Set a SPFieldUser field to a SPUser
SPUser user = web.Users[1];
item.SetFieldValueUser("Person", user);
 
// Set a SPFieldUser field to a list of SPPrincipal
SPGroup group = web.Groups[0];
SPUser user = web.Users[0];
SPUser user2 = web.EnsureUser("alexander.bruett");
SPUser user3 = web.EnsureUser("Domain Users"); ;
SPPrincipal[] principals = { group, user, user2, user3 };
item.SetFieldValueUser("AssignedTo", principals);

Especially setting fields that allow multiple values now needs only a couple of code lines.

SPFieldLookup

The SPFieldLookup field is a little bit more complicated if you want to set the field only by the lookup string. You have to query the ID of the lookup value before you can set the field value. The following extension methods simplify this task.

/// <summary>
/// Returns the value of a Lookup Field.
/// </summary>
private static string GetFieldValueLookup(this SPListItem item, 
    string fieldName)
{
    if (item != null)
    {
        SPFieldLookupValue lookupValue = 
            new SPFieldLookupValue(item[fieldName] as string);
        return lookupValue.LookupValue;
    }
    else
    {
        return string.Empty;
    }
}
 
/// <summary>
/// Returns the value of a Lookup-Field with multiple values.
/// </summary>
public static IEnumerable<string> GetFieldValueLookupCollection(
    this SPListItem item, string fieldName)
{
    List<string> result = new List<string>();
    if (item != null)
    {
        SPFieldLookupValueCollection values = 
            item[fieldName] as SPFieldLookupValueCollection;
 
        foreach (SPFieldLookupValue value in values)
        {
            result.Add(value.LookupValue);
        }
    }
    return result;
}
 
/// <summary>
/// Returns the SPFieldLookupValue instance of a lookup value. 
/// The ID value will be obtained using SPQuery.
/// </summary>
private static SPFieldLookupValue GetLookupValue(
    SPWeb web, SPFieldLookup field, string lookupValue)
{
    string queryFormat = 
        @"<Where>
            <Eq>
                <FieldRef Name='{0}' />
                <Value Type='Text'>{1}</Value>
            </Eq>
          </Where>";
 
    string queryText = 
        string.Format(queryFormat, field.LookupField, lookupValue);
    SPList lookupList = web.Lists[new Guid(field.LookupList)];
 
    SPListItemCollection lookupItems = 
        lookupList.GetItems(new SPQuery() { Query = queryText });
 
    if (lookupItems.Count > 0)
    {
        int lookupId = 
            Convert.ToInt32(lookupItems[0][SPBuiltInFieldId.ID]);
 
        return new SPFieldLookupValue(lookupId, lookupValue);
    }
    else
    {
        return null;
    }
}
 
/// <summary>
/// Sets the value of a Lookup-Field.
/// </summary>
public static void SetFieldValueLookup(
    this SPListItem item, string fieldName, string lookupValue)
{
    if (item != null)
    {
        SPFieldLookup field = 
            item.Fields.GetField(fieldName) as SPFieldLookup;
        item[fieldName] = GetLookupValue(item.Web, field, lookupValue);
    }
    else
    {
        item[fieldName] = null;
    }
}
 
/// <summary>
/// Set the values of a Lookup-Field with multiple values allowed.
/// </summary>
public static void SetFieldValueLookup(this SPListItem item, 
    string fieldName, IEnumerable<string> lookupValues)
{
    if (item != null)
    {
        SPFieldLookup field = 
            item.Fields.GetField(fieldName) as SPFieldLookup;
 
        SPFieldLookupValueCollection fieldValues = 
            new SPFieldLookupValueCollection();
 
        foreach (string lookupValue in lookupValues)
        {
            fieldValues.Add(
                GetLookupValue(item.Web, field, lookupValue));
        }
        item[fieldName] = fieldValues;
    }
}

That’s been a lot of code but take a look at the following lines of code. Especially the setting task becomes very easy now.

// Reads the value of a SPFieldLookup field
string value = item.GetFieldValueLookup("LookupFieldName");
 
// Read lookup values of a SPFieldLookup field 
// with multiple values allowed
IEnumerable<string> values = 
  item.GetFieldValueLookupCollection("MultiLookupFieldName");
 
// Set the value of a SPFieldLookup field
item.SetFieldValueLookup("LookupFieldName", "LookupValue");
 
//Set the value of a SPFieldLookup field with multiple values allowed
string[] values = {"Hamburg", "London" };
item.SetFieldValueLookup("MultiLookupFieldName", values);

SPFieldUrl

Setting and getting SPFieldUrl field values is very simple:

/// <summary>
/// Returns the value of an Url-Field.
/// </summary>
public static string GetFieldValueUrl(
    this SPListItem item, string fieldName)
{
    if (item != null)
    {
        SPFieldUrlValue urlValue = 
            new SPFieldUrlValue(item[fieldName] as string);
        return urlValue.Url;
    }
    else
    {
        return string.Empty;
    }
}
 
/// <summary>
/// Sets the value of an URL-Field.
/// </summary>
public static void SetFieldValueUrl(this SPListItem item, 
    string fieldName, string url, string description)
{
    if (item != null)
    {
        item[fieldName] = 
            new SPFieldUrlValue() 
                { 
                    Description = description, 
                    Url = url 
                };
    }
}

The following lines of code show how to get and set values of the SPFieldUrl field using the extension methods above:

// Get the url of a SPFieldUrl field
string url = item.GetFieldValueUrl("URL");
 
// Set the url and description of a SPFieldUrl field
item.SetFieldValueUrl("URL", "http://www.alexbruett.net", "Alex' Blog");

Conclusion

Using extension methods to simplify the access to complex and SharePoint list fields makes your code more readable and reduces the lines of code.

You could also use helper classes instead of extension methods but you will have to write more code to call a helper method instead of calling a extension method.

Tags: , , , , , , ,

Query whole site collection using SPSiteDataQuery

Februar 6th, 2009 | 1 Comment | Posted in .NET, SharePoint

Using the SPQuery class you can query one SharePoint list for items.

To set up a query across a whole site collection you can use the SPSiteDataQuery object.

The following method fetches all .doc files from all doclibs of the site collection and prints out a list of urls to those items.

public void TestSiteDataQuery()
{
  using (SPSite site = new SPSite("http://localhost"))
  {
    using (SPWeb web = site.OpenWeb("/"))
    {
      SPSiteDataQuery query = new SPSiteDataQuery();
 
      // Search in doclibs only
      query.Lists = "<Lists BaseType='1' />";
 
      // Only .doc files
      query.Query =
      @"<Where>
          <Eq>
            <FieldRef Name='DocIcon' />
            <Value Type='Computed'>doc</Value>
          </Eq>
        </Where>";
 
      // Select only needed columns: file reference
      query.ViewFields = "<FieldRef Name='FileRef' />";
 
      // Search in all webs of the site collection
      query.Webs = "<Webs Scope='SiteCollection' />";
 
      // Perform the query
      DataTable table = web.GetSiteData(query);
 
      // Generate an absolute url for each document
      foreach (DataRow row in table.Rows)
      {
        string relativeUrl = 
          row["FileRef"].ToString().Substring(
            row["FileRef"].ToString().IndexOf("#") + 1);
        string fullUrl = site.MakeFullUrl(relativeUrl);
 
        // Write urls to console
        Console.WriteLine(fullUrl);
      }
    }
  }
}
Tags: , , ,

Read Word Document Properties from SharePoint property bag

Mai 6th, 2008 | 1 Comment | Posted in .NET, SharePoint

Word documents have some extended properties like category, title or comments wich your can edit within word. In some cases you might want to read these document properties from code deployed within SharePoint. For example if you want to create a content type from a document and set the description of the content type to the value of the document’s comments.

The following example runs through all items of the document library “documents” on the root site and prints out document properties.

using (SPSite site = new SPSite("http://localhost"))
{
  using (SPWeb web = site.OpenWeb())
  {
    SPDocumentLibrary lib = (SPDocumentLibrary)web.Lists["Documents"];
    foreach (SPListItem item in lib.Items)
    {
      if (item.File.Properties.Contains("_Comments"))
    {
        Console.WriteLine("File {0} contains comment {1}.", 
          item.File.Name, item.File.Properties["_Comments"]);
      }
      if (item.File.Properties.Contains("_Category"))
     {
        Console.WriteLine("File {0} contains category {1}.", 
          item.File.Name, item.File.Properties["_Category"]);
      }
      if (item.File.Properties.Contains("Subject"))
      {
        Console.WriteLine("File {0} contains subject {1}.", 
          item.File.Name, item.File.Properties["Subject"]);
      }
      if (item.File.Properties.Contains("Keywords"))
     {
        Console.WriteLine("File {0} contains keywords {1}.", 
          item.File.Name, item.File.Properties["Keywords"]);
      }
    }
  }
}
Tags: , ,

Change SharePoint ContentType of ListItem

Mai 4th, 2008 | 1 Comment | Posted in .NET, SharePoint

The user interface of SharePoint allows you to select or change the ContentType of a list item. I asked myself how this could be done by code. It wasn’t as easy as I thought.

The class ListItem has a property ContentType but it’s readonly. I had to reflect the Microsoft.SharePoint.dll and finally used this workaround to change the content type:

void SetContentType (SPListItem item, SPContentType ct)
{
  item["ContentTypeId"] = ct.Id;
  item.Update();
}

In addition I wanted to set the ContentType of ListItems to their parent content type. Setting the content type to the type of the parent content type doesn’t change anything because item.ContentType.Parent and item.ContentType are equal. So I tried the parent of the parent and it worked:

void SetContentTypeToParentType (SPListItem item)
{
  item["ContentTypeId"] = item.ContentType.Parent.Parent.Id;
  item.Update();
}
Tags:

Hello world!

April 18th, 2008 | 2 Comments | Posted in .NET

Welcome to my development blog. This is my first post with a hello world example to check out how the syntax highlightning plugin works together with my theme.

public class Hello
{
  ///<summary>
  ///This program says Hello World!
  ///</summary>
  public static void main(String[] args)
  {
    // Write a line to the console
    Console.WriteLine("Hello World!");
  }
}

This is a wordpress blog I use the WP-Syntax plugin for syntax highlightning and the Statement theme as template for my theme and the tag cloud plugin from kl3tte.