Setting SharePoint 2013 Field Title Using Code Not Working As Expected


Recently bumped up against an issue in SharePoint 2013 which I think is a bug.

The Problem

In my development VM (SharePoint 2013 with October 2013 CU build 15.0.4551.1005) changing a column title using code does not work completely. I created a simple list with a custom list column of type Text.

To start, my column is named “My Custom Column”

Custom Column 1

I change the column Title in the UI, which changes the DisplayName attribute in the field’s SchemaXml property but not the SPField.Title property value.

Changed via the UI

Now if we look at the field definition using some powershell

$w=get-spweb "http://pub.pdogs.local"
$l=$w.Lists["Simple List"]
$f = $l.Fields.GetFieldByInternalName("MyCustomColumn")
$f.Title
$f.TitleResource.Value
$f.SchemaXml

We see that the DisplayName attribute of the SchemaXml property reflects the new title, but the SPField.Title property does not;

After change via the UI

So lets try changing this using some code;

$w=get-spweb "http://pub.pdogs.local"
$l=$w.Lists["Simple List"]
$f = $l.Fields.GetFieldByInternalName("MyCustomColumn")
$f.Title
$f.TitleResource.Value
$f.SchemaXml
"`n"
$f.Title="Changed via code"
$f.Update()
$f.Title
$f.TitleResource.Value
$f.SchemaXml

$w.Dispose()

Changed via code

We see that the SPField.Title property has changed but the DisplayName attribute of the SchemaXml property has not changed, which we can see in the UI;

After changed via code

What gives? looking at the SPField.Title setter code using reflector we see a bunch of code which seems like it should work just fine;

SPField.Title Setter

So, given that the SPField.SchemaXml property is Read/Write we should be able to change the DisplayName attribute ourselves to affect the correct change;

$w = get-spweb "http://pub.pdogs.local"
$l = $w.Lists["Simple List"]
$f = $l.Fields.GetFieldByInternalName("MyCustomColumn")
if ($f -ne $null) {
    "$($f.SchemaXml)`n"
    $f.Title = "Changed via code 2"
    $xml = $f.SchemaXml
    $f.Title
    $f.TitleResource.Value
    "`n$xml`n"
    if ($xml -match "\s+DisplayName\s?=\s?`"([^`"]+)`"") {
        if ($matches[1] -ne $f.Title) {
            $xml = $xml -replace $matches[0], " DisplayName=`"$($f.Title)`""
            $f.SchemaXml = $xml
            $xml
        }
    }
}
$f.Update()
$w.Dispose()

The output from the powershell console shows the effects of running the script;

Changing via code

The 1st SchemaXml shown is before the change and DisplayName is set to “Changed via the UI” as expected.

We then set SPField.Title to “Changed via code 2” and expect the DisplayName of SchemaXml to have changed (refer to the SPField.Title code above), except it hasn’t, as shown in the 2nd SchemaXml displayed.

Our Powershell then updates the SchemaXml property itself after ‘manually’ changing the DisplayName attribute, as shown in the 3rd display of SchemaXml above before calling SPField.Update().

The change made this way results in the correct field name being shown in the UI;

Success

So all’s good then? Sadly not, now for some weirdness.

Lets change the field title back to it original value;

$w = get-spweb "http://pub.pdogs.local"
$l = $w.Lists["Simple List"]
$f = $l.Fields.GetFieldByInternalName("MyCustomColumn")
if ($f -ne $null) {
    "$($f.SchemaXml)`n"
    $f.Title = "My Custom Column"
    $xml = $f.SchemaXml
    $f.Title
    $f.TitleResource.Value
    "`n$xml`n"
    if ($xml -match "\s+DisplayName\s?=\s?`"([^`"]+)`"") {
        if ($matches[1] -ne $f.Title) {
            $xml = $xml -replace $matches[0], " DisplayName=`"$($f.Title)`""
            $f.SchemaXml = $xml
            $xml
        }
    }
}
$f.Update()
$w.Dispose()

After we run this the change is reflected in the UI;

Change back to original

But look at the powershell console output;

Weirdness

So the DisplayName attribute of the 1st SchemaXml is, as we would expect, the value of our last change.

After changing SPField.Title to “My Custom Column”, in the 2nd SchemaXml you’d expect DisplayName to be “My Custom Column”, except its changed back to the last value we set via the UI.

And then, as before, in the 3rd SchemaXml, we manually set the DisplayName attribute, so that’s also as we would expect.

Obviously this doesn’t seem right, and is most probably a bug, hopefully it is and not some general weirdness confined to my VM – if anyone reproduces this let me know.

I thought it may be something in the Powershell cmdlet code, but it’s the same using C# and the server API.

Published by

Phil Harding

SharePoint Consultant, Developer, Father, Husband and Climber.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s