2017-05-19 1 views
1

複数の値を選択できるようにする選択肢フィールド(AllowMultipleがtrue)を持つコンテンツ定義(CTD)がSenseNetにあります。 XML定義は、次のようになります。複数の選択肢が選択されているコンテンツをSenseNetにインポートできないのはなぜですか?

<Field name="Status" type="Choice"> 
    <DisplayName>Status</DisplayName> 
    <Configuration> 
    <AllowMultiple>true</AllowMultiple> 
    <Options> 
     <Option>In Processing</Option> 
     <Option>In Review</Option> 
     <Option>Tabled</Option> 
     <Option>Pending Verification</Option> 
     <Option>Approved</Option> 
    </Options> 
    </Configuration> 
</Field> 

私が選択した複数のオプションを使用してデータをエクスポートし、このフィールドのXML出力は;(セミコロン+スペース)との選択オプションを区切ると、次のようになります。

<Status>Pending Verification; Approved</Status> 

エクスポートしたデータをインポートしようとすると、エラーInvalidExtraValueが発生します。

この問題を解決するにはどうすればよいですか?

答えて

1

ここでの問題は、エクスポートされたXMLデータのセミコロンの後のスペースに関係しています。 SenseNetのインポート機能は、コンマまたはセミコロン区切り文字のいずれかを探してXMLデータ文字列を分割し、値のList<string>コレクションを返します。あなたが推測したように、先頭のスペースは削除されず、有効な選択肢オプションとの比較に失敗します。

この問題を解決する方法は2つあります。データを変更するか、ソースコードを変更することができます。

この

<Status>Pending Verification; Approved</Status> 

たが、これに変更されるように、あなたは、すべての先頭のスペースが削除されるように、エクスポートしたデータを変更するためのスクリプトを実行することができ、データ

を変更

<Status>Pending Verification;Approved</Status> 

ソースコードを変更

SenseNetのソースコードをコンパイルすることができる場合は、ChoiceFields.csファイルSource\SenseNet\ContentRepository\FieldsのファイルConvertToStringListを変更する必要があります。返されるリストに追加されたすべての文字列がトリミングされていることを確認してください(String.Trim())。

この機能を以下のコードに置き換え、プロジェクトを再構築すると、インポートが正しく機能します。データを変更する必要はありません。

public static List<string> ConvertToStringList(object value) 
    { 
     List<string> list = value as List<string>; 
     if (list != null) 
      return list.Select(s => s.Trim()).ToList(); 

     list = new List<string>(); 
     string stringValue = value as string; 
     if (stringValue != null) 
     { 
      list.Add(stringValue); 
     } 
     else 
     { 
      IEnumerable enumerableValue = value as IEnumerable; 
      if (enumerableValue == null) 
      { 
       list.Add(value.ToString()); 
      } 
      else 
      { 
       foreach (object item in enumerableValue) 
        list.Add(item.ToString()); 
      } 
     } 
     return list.Select(s => s.Trim()).ToList(); 
    } 
+0

このコードはごみです。なぜ文字列をリストに変換したいのですか?なぜオブジェクトが時には文字列になるのか、それ以外のときにリストになるのでしょうか?実際の問題は、インポートメソッドがセミコロンをhtml特殊文字の一部と考えると思われます。参照:https://www.google.com/search?q=wiki+xml+html+special+characters&rlz=1C1OPRA_enUS563US647&oq=wiki+xml+html+special+characters&aqs=chrome..69i57.15711j0j7&sourceid=chrome&ie=UTF-8 – jdweng

+0

コードは、読者が望むほど読みにくくないかもしれませんが、ソースからかなりまっすぐです。これらのケースでは、関数の動作を変更しないことが不可欠です。これがあなたが見ているものです。 SenseNet Contentモデルを理解していれば、オブジェクトパラメータ(文字列、IEnumerable、Listなど)を取らなければならない理由を知ることができます。あなたの疑惑は間違っています。書かれたコードは問題を解決します。 –

+0

答えは大丈夫です、異なるタイプの変換はsensetetに関連しています、彼らは設計によるものです。 3番目のオプションは、オプション(ctd内の属性)の値を使用することです。そのようにすれば、人間が読めるオプションのテキストとオプションの値をスペースなしで同時に使用することができます。 –