May
8
2013
It's a well known issue that if you change the regional setting of a site collection with indexed columns an error is raised:
The column "column1" in the list or library "list1" has been marked for indexing. Please turn off all indexed columns before changing the collation of this site. You may re-index those columns after the collation of the site has been changed.
This alone is nothing special, but if you change the locale using PowerShell or ServerCode (see examples below), everything works fine without any errors.
$culture = [System.Globalization.CultureInfo]::CreateSpecificCulture(“sv-SE”)
$spWeb = Get-SPWeb http://someurl
$spWeb.Locale = $culture
$spWeb.Update()
$spWeb.Dispose()
Listing1 - PowerShell
SPContext.Current.Web.Locale = new CultureInfo("sv-SE");
SPContext.Current.Web.Update();
Listing2 - ServerCode
Because I had to change the locale on large site collections with lots of content, i wondered WHY SharePoint behaves like this and started a little research. There are three ways I want to inspect:
- The "Regional Settings Page", which is reached by selecting "Regional Settings" in the "Site Settings" area of a site collection.
- The "PowerShell Way", as described in Listing1 above.
- The "ServerCode Way" as described in Listing2 above.
My first discovery was that way two and three are acting exactly the same:
public void Update()
{
bool flag = this.m_bIsDirty || (this.m_spRegionalSettings != null && this.m_spRegionalSettings.IsDirty);
if (flag)
{
this.InitWeb();
uint lcid = (uint)this.m_lcid;
this.TraceWebOperation("Update", true);
uint collationLCID;
this.Request.SetWebProps([...Many Properties...]);
this.m_webVersion += 1u;
this.RegionalSettings.SetCollationLCID(collationLCID);
this.RegionalSettings.IsDirty = false;
this.m_bIsDirty = false;
}
}
Listing3 - SPWeb.Update()
When executing SPWeb.Update(), SharePoint checks if the locale was changed. If yes, SPWeb gets reinited and "RegionalSettings.SetCollationLCID" is called, which does nothing more than this:
internal void SetCollationLCID(uint lcidCollation)
{
this.m_lcidCollation = lcidCollation;
}
Listing4 - SetCollationLCID
So, what does the first way, the Regional Settings Page? If we take a look at the .aspx Page ("regionalsetng.aspx", located in "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\template\layouts"), we can see that the onClick Event of the "OK" button is bound to "BtnUpdateRegionalSettings_Click". The DLL for SharePoint ApplicationPages is located at "C:\inetpub\wwwroot\wss\VirtualDirectories\<yourwebapp>\_app_bin". Using ILSpy we can see what "BtnUpdateRegionalSettings_Click" does:
bool bIndexed = false;
foreach (SPList sPList in sPWeb.Lists)
{
if (!sPList.HasExternalDataSource)
{
foreach (SPField sPField in sPList.Fields)
{
if (sPField.Indexed && (sPField.Type == SPFieldType.Text || sPField.Type == SPFieldType.Choice))
{
bIndexed = true;
try
{
SPList sPList2 = this.Web.Lists[sPList.ID];
if (sPList2.DoesUserHavePermissions(SPBasePermissions.Open))
{
strNvpList = sPList.Title;
strNvpField = sPField.Title;
}
break;
}
catch
{
break;
}
}
}
if (strNvpField != null)
{
break;
}
}
}
Listing5 - BtnUpdateRegionalSettings_Click
If the locale setting was changed, a simple foreach is executed which iterates through all fields in all lists in the current web. If a field is indexed and has the type "SPFieldType.Text" or "SPFieldType.Choice" a bool is set to true and the loop leaved. Afterwards an exception is thrown, which leads us to the beginning of this article.
I have to admit, I still dont know WHY SharePoint is acting like this
Even though I will try it the "PowerShell Way" and see what happens. If anyone knows the reason for this behaviour, feel free to contact me or comment.
.net,
2010,
aspx,
c#,
linus winterseel,
microsoft,
sharepoint 2010,
sharepoint2010,
spweb,
clientcontext,
regional settings,
ilspy,
assembly,
locale