AddFieldAsXml cannot be used to set the InternalName correctly

All fields in SharePoint lists (and doclibs which are specialized lists) have two names. An Internal Name that's used by SharePoint and the Object Model (among other things) and an Display Name which is what you see in your Browser. There are four ways you can create a new field on a list in SharePoint.

  1. Simply use the Web Interface and add a new column. When you add the column, the name you give it at creation time is set as both the Internal Name and the Display Name. Anytime after that when you change the name you're only changing the Display Name.
  2. Create a custom site definition with SCHEMA.XML. Here you can set both the Internal Name and Display Name but the user would be able (with the right privledges) to change the Display Name.
  3. Create a field using the AddField method of the SPFieldCollection class. Here you can only set the Display Name. The Internal Name will get autogenerated by SharePoint so you have no control over it. There are rules around what that Internal Name will be and you could write your own routine to figure that out, but that's beyond the scope of this posting.
  4. Create a field using the AddFieldAsXml method of the SPFieldCollection class. Here it's the same thing as the previous method but you specify the CAML for the field (same CAML as you would specify in a SCHEMA.XML file). This has the most flexiblity but also has a bug which is the point of this post.

The Problem

So you decide you're going to dynamically update a list using a snippet of CAML and make a call to the AddFieldAsXml method. Let's say your CAML looks something like this:

string newField = "<Field Type=\"Text\" "DisplayName=\"NewFieldDisplayName\" "Name=\"NewFieldInternalName\"/>";
myFieldCollection.AddFieldAsXml(newField);

So you expect to create a field with a Display Name of "NewFieldDisplayName" and an internal name of "NewFieldInternalName" right? Wrong. After the method call you take a look at the field. Lo and behold, SharePoint has basically ignored your request to make the internal name "NewFieldInternalName" and instead set it to "NewFieldDisplayName". Blech! That's NOT what I asked for.

The Fix

The fix is a little two-step that you have to do with SharePoint to get the desired result when using the AddFieldAsXml method:

  1. Define your CAML so that the Internal Name you want to use is actually set as the Display Name
  2. Create the field with the call to AddFieldAsXml
  3. After the field is created, retrieve it using the internal name and set the Title property to the real Display Name you wanted it to be in the first place

So a simple little snippet to do this would be (this assumes you have some CAML and a SPFieldCollection first):

/// <summary>

/// Adds a field as XML to a SharePoint field collection. This fixes the AddFieldAsXml bug SharePoint has.

/// </summary>

/// <param name="fields">Field collection to add the new field to.</param>

private void AddFieldAsXml(SPFieldCollection fields)

{

    // Declare our intent for our names here

    string internalName = "NewFieldInternalName";

    string displayName = "NewFieldDisplayName";

 

    // Our definition for the CAML. Note that DisplayName is really our internal name here

    string newField = "<Field Type=\"Text\" DisplayName=\"NewFieldInternalName\" Name=\"NewFieldInternalName\"/>";

 

    // Call the SharePoint method to create the field.

    fields.AddFieldAsXml(newField);

 

    // Retrieve the newly created field using the internal name

    SPField field = fields[internalName];

 

    // Reset the title to the name we want it to be (after AddFieldAsXml the display name will be the internal name)

    field.Title = displayName;

 

    // Finally commit the updates to the field

    field.Update();

}

Feel free to use this and update it (maybe passing in the field names or even put it into a class). Hope that helps. Many thanks to Brian on our team for coming up with a solution.

 

 

5 Comments

  • Hi Bil,

    it took me a few attempts before trying a search for "AddFieldAsXml bug"... The behavior is the same in SharePoint 2010, I would like to hear MS opinion on this - probably they don't consider it a bug :)
    Thank you for the workaround!

  • Half Abude, I agree, it would have been nice for MS to fix this in SP 2010.

  • I am doing this with powershell, and for some reason the Title is set correct but the DisplayName in the Schema is not updated. So the the name displayed is still the internal name. Any ideas?

  • AddFieldAsXml works with correct DisplayName and InternalName for us when using the Template Pattern. But we encounter the issue, when creating it from feature reciever!!

  • Theres no bug, - just remember to specify the op parameter(3rd parameter) to SPAddFieldOptions.AddFieldInternalNameHint, then it works(In MOSS 2007, - and probably also SP2010)

Comments have been disabled for this content.