SharePoint Document Library and List Column Names

22 07 2009

Any time you want to address a Document Library or List using CAML, or you want to populate a Document Library or List item metadata using the Object Model, you invariably need to know the “internal” names of the columns.

With CAML you have to use the internal column name, as opposed to the columns display name, so how do you find out what the iternal column names are? If it’s for a list you’ve created, and you haven’t changed any column names, then the internal names match the display names. If  you change the column name, it’s internal name remains the same as when originally created and only the display name is changed.

And you can always check what the internal column names are, using the CAML Query Builder tool.

camlresultview

So far so good, how about OOTB column names. like “Title”, “Name” and so on, or custom column names whose internal name seems to bear no resemblance to its display name. Well there’s another trick, navigate to your list/document library and ensure that the required columns are displayed on some View.

coldocview

Here I’ve chosen the following columns to display on the View:

  • Name (linked to document with edit menu)
  • Name (linked to document)
  • Name (for use in forms)
  • Title
  • Type (icon linked to document)

To find out what the internal names for these columns are, click on the column header to sort the list by that column, then take a look at the URL in your browser;

coldocview1

I clicked on the Name column (the one with the edit menu), looking at the SortField parameter in the URL, this turns out to be the “LinkFilename” column. Clicking on the Type column shows me that the internal name for this is “DocIcon”.

coldocview2





Sharepoint (MOSS): Creating Document Library Items / Uploading Files to a Document Library

14 01 2009

Creating Sharepoint (MOSS) List items is pretty straight forward using Sharepoints Webservices, it’s also straight forward to create Sharepoint Document Library items using Sharepoints Webservices, and as a bonus you don’t have use any CAML.

Using the CopyIntoItems method of the Sharepoint Copy Webservice you can upload a new file into a document library, and/or create a new document library item based on a copy from some other Sharepoint source, i.e. a  linked copy (more on this at the end of the post). When creating the document library item this method also allows you to set the items column meta data, in one operation, anyway, enough talk more code….

private void UploadToSharepointDocumentLibrary( string documentLibraryName,
                CopySoapClient spCopySvc,
                string cDescription,
                string libraryItemUrl,
                string libraryItemFileXml)
{
 string[] targetUrls = new[] { libraryItemUrl };
 byte[] libraryItemBytes = Encoding.ASCII.GetBytes(libraryItemFileXml);

 // library item meta data (columns)
 List<FieldInformation> metaData = new List<FieldInformation>();
 var fi = new FieldInformation();
 fi.DisplayName = "Description";
 fi.InternalName = "Description0";
 fi.Type = FieldType.Note;
 fi.Value = cDescription;
 metaData.Add(fi);

 // call SP wbservice
 CopyResult[] cResults;
 spCopySvc.CopyIntoItems("+", targetUrls, metaData.ToArray(), libraryItemBytes, out cResults);
 if (cResults.Length < 1)
    writeLineTrace("Unable to create a document library item");
 else if (cResults[0].ErrorCode != CopyErrorCode.Success)
 {
    writeLineTrace(
       string.Format(
          "Unable to create a document library item,{0}- ErrorCode = {1}{0}- ErrorMessage = {2}{0}- Destination Url = {3}",
            Environment.NewLine, cResults[0].ErrorCode, cResults[0].ErrorMessage, cResults[0].DestinationUrl));
 }
 else
 {
    writeLineTrace(string.Format("Created a document library item"));
    UnlinkDocumentLibraryItem(documentLibraryName, libraryItemUrl);
 }
}

Note:

documentLibraryName is the unencoded name of (only) the document library including space characters.

libraryItemUrl is the full URL of the document library item, and this URL should be URL encoded (spaces replaced with %20 etc) 

The use of the FieldInformation class to assign meta data to the document library item

Notice the 1st parameter to the CopyIntoItems method where I pass a “+” character. This parameter should contain the source url of the item being copied (and uploaded), however very handily, you can pass anything in this parameter except the empty string, and therefore using this technique you can introduce/upload new document library items and not just new items based on copies of items from elsewhere. The CopyIntoItems method does not validate the source url passed, so it’s safe to put anything in there, except the empty string, in which case the method call fails.

Linked Copies.

Using the technique described above creates a new document library item which is based on a copy of the source item (1st parameter), what Sharepoint calls a Linked Copy. If you look at the properties for a document library item which is a linked copy you’ll see something like;

Linked Copy Properties

If you pass a valid URL as the 1st parameter to CopyIntoItems, then this is what you’ll see when you view the new items properties. This may be a problem, or not, and as you can see you can unlink the new item (the copy!) from it’s source. If you pass a space character, or the ”+” sign as I’ve done, as the 1st parameter, when you view the new items properties you won’t see this message at all, Sharepoint “mostly” treats it as if it weren’t a copy. I say mostly, because if you expand the items control menu, you’ll see the “Go to Source Item” menu command displayed, clicking on this however does nothing.

Linked Copy Control Menu

So, how do you completely “Unlink” a copy (even if it’s a fake copy!) from it’s source. The answer for me turns out not to work, however, other people seem to have had it working though so I’ll present my code here, which also demonstrates nicely how you can use LINQ to XML classes with Sharepoint. The UnlinkDocumentLibraryItem(…) method attempts to set the document library items internal “_CopySource” field to an empty string in order to get rid of the command menus “Go to Source Item” command, for me this doesn’t work, although I get no error message, though other people have reported this to work.

private void UnlinkDocumentLibraryItem(string documentLibraryName, string libraryItemUrl)
{
 string listsSvcUrl = ConfigurationManager.AppSettings["mboscatlistsurl"];
 if (string.IsNullOrEmpty(listsSvcUrl) || string.IsNullOrEmpty(documentLibraryName) ||
         string.IsNullOrEmpty(libraryItemUrl))
  return;
 // create a service binding with security
 var svcBinding = CreateBinding<BasicHttpBinding>(new TimeSpan(0, 10, 0));
 CreateSecurityBinding(svcBinding);
 // create the svc
 EndpointAddress listsSvcEndpoint = new EndpointAddress(listsSvcUrl);
 var spListsSvc = new ListsSoapClient(svcBinding, listsSvcEndpoint);
 spListsSvc.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
 // create the CAML query
 var caml = new XElement("Batch"
         , new XAttribute("OnError", "Continue")
         , new XAttribute("PreCalc", "TRUE")
         , new XElement("Method"
              , new XAttribute("ID", "1")
              , new XAttribute("Cmd", "Update")
              , new XElement("Field"
                   , new XAttribute("Name", "ID")
               )
              , new XElement("Field"
                   , new XAttribute("Name", "FileRef")
                   , new XText(libraryItemUrl.Replace("%20", " "))
               )
              , new XElement("Field"
                   , new XAttribute("Name", "_CopySource")
                   , new XText("")
               )
          )
  );
 XmlNode ndResults = spListsSvc.UpdateListItems(documentLibraryName, caml.GetXmlElement());
 var listItemResult = CheckListUpdateResults(ndResults);
 if (listItemResult.Key < 1)
    writeLineTrace(string.Format("Unable to Unlink system exception report @ Mbos: {0}", listItemResult.Value));
 else
    writeLineTrace(string.Format("Unlinked system exception report @ Mbos"));
}

Note:
documentLibraryName is the unencoded name of (only) the document library including space characters.

libraryItemUrl is the full URL of the document library item, and this URL should not be URL encoded (%20 replaced with space etc).

The use of the FileRef field in the CAML query which is used to locate the document library item to update, in contrast to updating List items which requires the ID field be used to locate the list item to update.

Check here for the CheckListUpdateResults(…) method.

In order to use LINQ to XML classes with Sharepoint Webservices, you’ll need to convert an XElement to say an XmlNode and vice versa, and C# 3.0 extension methods are perfect for this

public static class MyExtensions
{
 public static XElement GetXElement(this XmlNode node)
 {
     XDocument xDoc = new XDocument();
     using (XmlWriter xmlWriter = xDoc.CreateWriter())
     {
        node.WriteTo(xmlWriter);
     }
     return xDoc.Root;
 }

 public static XmlNode GetXmlNode(this XElement element)
 {
     var xnNode = (XmlNode)GetXmlDocument(element);
     return xnNode;
 }

 public static XmlDocument GetXmlDocument(this XElement element)
 {
     using (XmlReader xmlReader = element.CreateReader())
     {
         XmlDocument xmlDoc = new XmlDocument();
         xmlDoc.Load(xmlReader);
         return xmlDoc;
     }
 }

 public static XmlElement GetXmlElement(this XElement element)
 {
     var xeNode = GetXmlDocument(element).DocumentElement;
     return xeNode;
 }
}

.