ディスクにシリアル化しようとしている監視可能なコレクションがあります。受け取ったエラーは次のとおりです。
Type 'VisuallySpeaking.Data.GrammarList' with data contract name
'GrammarList:http://schemas.datacontract.org/2004/07/VisuallySpeaking.Data'
is not expected. Consider using a DataContractResolver or add any
types not known statically to the list of known types - for example,
by using the KnownTypeAttribute attribute or by adding them to the
list of known types passed to
DataContractSerializer."} System.Exception
{System.Runtime.Serialization.SerializationException}
ここに私のデータオブジェクトがあります:
namespace VisuallySpeaking.Data
{
[CollectionDataContract]
public class GrammarList : ObservableCollection<GrammarDataObject>
{
public GrammarList() : base()
{
Add(new GrammarDataObject("My Name", "My name is","Assets/SampleAssets/MyName.png"));
Add(new GrammarDataObject("Where is", "Where is",""));
Add(new GrammarDataObject("Dog", "I have a dog","/Assets/SampleAssets/westie.jpg"));
}
}
[DataContract]
public class GrammarDataObject : VisuallySpeaking.Common.BindableBase
{
private string _Name;
private string _SpeakingText;
private string _ImagePath;
public GrammarDataObject(string Name, string SpeakingText, string ImagePath)
{
this.Name = Name;
this.SpeakingText = SpeakingText;
this.ImagePath = ImagePath;
}
[DataMember]
public string Name
{
get { return _Name; }
set
{
if (this._Name != value)
{
this._Name = value;
this.OnPropertyChanged("Name");
}
}
}
[DataMember]
public string SpeakingText
{
get { return _SpeakingText; }
set
{
if (this._SpeakingText != value)
{
this._SpeakingText = value;
this.OnPropertyChanged("SpeakingText");
}
}
}
[DataMember]
public string ImagePath
{
get { return _ImagePath; }
set
{
if (this._ImagePath != value)
{
this._ImagePath = value;
this.OnPropertyChanged("ImagePath");
}
}
}
}
Fresh のコメントに基づいて、ここにも BindableBase を追加しました。
namespace VisuallySpeaking.Common
{
/// <summary>
/// Implementation of <see cref="INotifyPropertyChanged"/> to simplify models.
/// </summary>
[Windows.Foundation.Metadata.WebHostHidden]
[DataContract(IsReference = true)]
public abstract class BindableBase : INotifyPropertyChanged
{
/// <summary>
/// Multicast event for property change notifications.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Checks if a property already matches a desired value. Sets the property and
/// notifies listeners only when necessary.
/// </summary>
/// <typeparam name="T">Type of the property.</typeparam>
/// <param name="storage">Reference to a property with both getter and setter.</param>
/// <param name="value">Desired value for the property.</param>
/// <param name="propertyName">Name of the property used to notify listeners. This
/// value is optional and can be provided automatically when invoked from compilers that
/// support CallerMemberName.</param>
/// <returns>True if the value was changed, false if the existing value matched the
/// desired value.</returns>
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
{
if (object.Equals(storage, value)) return false;
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
/// <summary>
/// Notifies listeners that a property value has changed.
/// </summary>
/// <param name="propertyName">Name of the property used to notify listeners. This
/// value is optional and can be provided automatically when invoked from compilers
/// that support <see cref="CallerMemberNameAttribute"/>.</param>
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
どういうわけかGrammarList
クラスを間違ってマークしたと思いますが、解決方法についてはわかりません。
更新: エラー メッセージに続いて (もちろん)、KnowTypeAttribute を追加したところ、動作しているように見えました。
[CollectionDataContract(Name = "GrammarList"),KnownType(typeof(GrammarList))]
public class GrammarList : ObservableCollection<GrammarDataObject>
繰り返しになりますが、Fresh のおかげで、CollectionDataContract を Name="GrammarList" で更新しましたが、ディスクから XML ファイルを復元するときに問題が発生しました。次のエラー メッセージが表示されます。
名前空間 ' http://schemas.datacontract.org/2004/07/VisuallySpeaking.Data ' から要素 'GrammarList' を期待しています..名前 'GrammarDataObject'、名前空間 ' http://schemas.datacontract.org/の 'Element' が見つかりました2004/07/VisuallySpeaking.Data '.
シリアライズされた XML は次のようになります。
<?xml version="1.0"?>
<GrammarDataObject xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/VisuallySpeaking.Data" i:type="GrammarList">
<GrammarDataObject xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="i1">
<ImagePath>Assets/SampleAssets/MyName.png</ImagePath>
<Name>My Name</Name>
<SpeakingText>My name is</SpeakingText>
</GrammarDataObject>
<GrammarDataObject xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="i3">
<ImagePath/>
<Name>Where is</Name>
<SpeakingText>Where is</SpeakingText>
</GrammarDataObject>
<GrammarDataObject xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="i4">
<ImagePath>/Assets/SampleAssets/westie.jpg</ImagePath>
<Name>Dog</Name>
<SpeakingText>I have a dog</SpeakingText>
</GrammarDataObject>
</GrammarDataObject>
XML 外部タグが「GrammarList」としてリストされないのはなぜですか? それがデシリアライザーが探しているものだと思います。シリアル化された xml を手動で編集して GrammarList を外部タグとして配置すると、適切に逆シリアル化されます。私はまた何かが欠けていると確信しています!
UPDATE AGAIN シリアル化していたとき、次のコードがありました。
DataContractSerializer serializer = new DataContractSerializer(typeof(GrammarDataObject));
GrammarList と presto にシリアル化するように変更し、修正しました!!! 助けてくれてありがとうフレッシュ。
DataContractSerializer serializer = new DataContractSerializer(typeof(GrammarList));