サポートされていないフィールドタイプの変更
-
16-10-2019 - |
質問
SP2007のカスタムサイト列に問題があり、そのフィールドタイプが最近変更されました。サイトコレクションの範囲で展開されている次のアーティファクトの機能を定義しました。
- いくつかのカスタムサイト列を含む機能
- 要素を使用してカスタムサイト列を参照するカスタムコンテンツタイプを含む機能
- カスタムサイト列を参照し、カスタムコンテンツタイプを適用するカスタムリストテンプレート(組み込みのカスタムリストテンプレートに基づく)を含む機能。
最近、カスタムサイト列の1つのスキーマを変更しました。具体的には、「タイプ」属性を「テキスト」から「ノート」に変更しました。これが元のスキーマです:
<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)at microsoft.sharepoint.library.sprequest.updatefield(bstrurl、bstrilistname、string bstrxml)
問題を解決するためにできることはありますか(フィールドスキーマを戻す以外)、または私たちは立ち往生していますか?
解決
興味深い - 私はこのまさにこのシナリオ(テキストからメモへのフィールドをアップグレードする)を最近カンファレンストークでデモで使用し、SharePoint 2010の新しいアップグレード可能な機能フレームワークを披露しました。 SP2007とSP2010の両方で、使用しているフィールドのタイプの変更は、発見したとおり、サポートされていません。
私の推奨事項は次のとおりです。
- ロールバックが何らかの形で問題が機能する場合に備えて、バックアップを取得します。
- フィールドスキーマを「テキスト」に戻します。
- 別のアプローチを使用して、フィールドタイプを変更します。
- 新しいノートフィールドを提供します
- すべてのリストを反復し、古いフィールドから新しいフィールドにデータをコピーするコードを書き込む
- 古いフィールドを隠したものとしてマークします
明らかに、多くのサイト/ウェブ/リスト/リストアイテムがある場合、いくつかのことを考える必要がありますが、元のルートを下っていなくても、スケールチャレンジがあります。
有用な場合は、私が使用したコードを次に示します(私の場合は、SP2010 Feature -Upgradingイベントで、機能するイベントなどで適切に使用できます)。これは、リストを含むすべてのWebでアップグレードされた(つまり、SP2007でアクティブ化された)Web機能にありました。
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);
}
}
}
});
}