-
16-10-2019 - |
题
我在SP2007中的自定义站点列有问题,该字段类型最近更改了。我已经为以下工件定义了功能,该功能已在网站收集范围内部署:
- 包含几个自定义站点列的功能
- 包含自定义内容类型的功能,该功能使用元素引用自定义站点列
- 包含自定义列表模板的功能(基于内置自定义列表模板),该功能引用自定义站点列,并应用自定义内容类型。
我们最近更改了一个自定义站点列的架构。具体来说,我们将“类型”属性从“文本”更改为“ Note”。这是原始模式:
<Field ID="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
SourceID="http://schemas.microsoft.com/sharepoint/v3"
Name="CurrentStatus"
StaticName="CurrentStatus"
Group="My Site Columns"
ColName="CurrentStatus"
Type="Text"
ShowInEditForm="FALSE"
ShowInNewForm="FALSE"
ShowInFileDlg="FALSE"
DisplayName="Current Status"
Description="The current status.">
</Field>
这是具有新“注释”类型的更新架构:
<Field ID="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
SourceID="http://schemas.microsoft.com/sharepoint/v3"
Name="CurrentStatus"
StaticName="CurrentStatus"
Group="My Site Columns"
ColName="CurrentStatus"
Type="Note"
RichText="TRUE"
IsolateStyles="TRUE"
RichTextMode="FullHtml"
ShowInEditForm="FALSE"
ShowInNewForm="FALSE"
ShowInFileDlg="FALSE"
DisplayName="Current Status"
Description="The current status.">
</Field>
现在,我认识到这不是支持的变化,我计划将来不惜一切代价避免这种变化。但是在我们的初始测试中,我们发现我们所有现有的列表(使用旧站点列架构创建)在部署新功能后似乎无需升级到新架构。但是,偶尔在某些系统上,我们发现每当有人试图从我们的模板中创建列表的新实例时,就会发生以下错误:
非支撑场类型更改。
该字段不能更改为新类型。请检查新类型,然后重试。在Microsoft.sharepoint.library.sprequestinternalclass.updatefield(String bstrurl,String bstrlistname,String bstrxml)上,请访问Microsoft.sharepoint.library.sprequest.update.update.updatefield(String bstrurl,string bstrurl,string bstrlistname,string bstrlistname string bstrxmml)
我们可以做些什么来解决问题(除了重新恢复字段模式),还是我们卡住了?
解决方案
有趣的是 - 我最近在一次会议演讲中使用了这种情况(将字段从文本升级到注释),以展示SharePoint 2010的新升级功能框架。在SP2007和SP2010中,正如您发现的那样,更改所使用的字段的类型都是不受限制的。
我的建议是:
- 如果以某种方式回滚,请采取备份。
- 将字段模式恢复回到“文本”。
- 使用不同的方法来更改字段类型,即:
- 提供新笔记字段
- 写代码以迭代所有列表,并将来自旧字段的数据复制到新的
- 将旧字段标记为隐藏
显然,如果您有很多网站/网/列表/列表项目,您将需要考虑一些事情,但是即使您没有走过原始路线,您也会有规模的挑战。
如果它很有用,这是我使用的代码(就我的情况而言,在SP2010功能求和事件中,但是您可以在功能激活的事件或类似的功能中适当地使用它)。请注意,这是在包含该列表的所有网络上升级的Web功能(IE激活的SP2007):
List<SPField> fieldsToUpgrade = new List<SPField>();
// find all the lists in this web using the 'Tourist Activity' content type..
SPListCollection genericLists = parentWeb.GetListsOfType(SPBaseType.GenericList);
foreach (SPList list in genericLists)
{
if (list.ContentTypes[contentTypeName] != null)
{
// copy list data to new field..
foreach (SPListItem item in list.Items)
{
item[newFieldName] = item[oldFieldName];
item.SystemUpdate();
}
// mark old field as hidden..
SPField oldField = list.Fields.GetField(oldFieldName);
fieldsToUpgrade.Add(oldField);
}
}
foreach (SPField field in fieldsToUpgrade)
{
field.Hidden = true;
field.Update();
}
其他提示
你可以用我的方式做。
private static void ChangeFieldType() {
SPSecurity.RunWithElevatedPrivileges(delegate() {
using (SPSite site = new SPSite("YourSiteUrl")) {
using (SPWeb web = site.OpenWeb("YourWebUrl") {
try {
web.AllowUnsafeUpdates = true;
SPList list = web.Lists["YourListName"];
SPField changeTypeField = list.Fields["YourField"];
string schema;
schema = changeTypeField.SchemaXml;
schema = schema.Replace("Type=\"Text\"", "Type=\"Note\"");
changeTypeField.SchemaXml = schema;
changeTypeField.Update();
web.AllowUnsafeUpdates = false;
} catch (Exception e) {
Console.WriteLine(e.Message);
}
}
}
});
}