私は通知フレームワークを構築しています。そのために、送信したいすべてのクラスが派生する基本クラスをシリアライズおよびデシリアライズしています。
問題はコードがコンパイルされることですが、実際にこの基本クラスをシリアライズしようとすると、エラーが発生します
System.Runtime.Serialization.SerializationException: アセンブリ 'Xxx.DataContract, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' の Type 'Xxx.DataContracts.WQAllocationUpdate' は、シリアル化可能としてマークされていません。
コードは次のとおりです。
public class WCallUpdate : NotificationData
{
private string m_from = "";
[DataMember]
public string From
{
get { return m_from; }
set { m_from = value; }
}
private WCall m_wCall = new WCall();
[DataMember]
public WCall Call
{
get { return m_wCall; }
set { m_wCall = value; }
}
}
DataContract
通知の は次のとおりです。
/// <summary>
/// Basic class used in the notification service
/// </summary>
[DataContract]
public class NotificationData
{
}
/// <summary>
/// Enum containing all the events used in the application
/// </summary>
[DataContract]
public enum NotificationTypeKey
{
[EnumMember]
Default = 0,
[EnumMember]
IWorkQueueServiceAttributionAddedEvent = 1,
[EnumMember]
IWorkQueueServiceAttributionUpdatedEvent = 2,
[EnumMember]
IWorkQueueServiceAttributionRemovedEvent = 3,
}
データのシリアル化に使用されるコードは次のとおりです。
#region Create Message
/// <summary>
/// Creates a memoryStream from a notificationData
/// note: we insert also the notificationTypeKey at the beginning of the
/// stream in order to treat the memoryStream correctly on the client side
/// </summary>
/// <param name="notificationTypeKey"></param>
/// <param name="notificationData"></param>
/// <returns></returns>
public MemoryStream CreateMessage(NotificationTypeKey notificationTypeKey, NotificationData notificationData)
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
try
{
formatter.Serialize(stream, notificationTypeKey);
formatter.Serialize(stream, notificationData);
}
catch (Exception ex)
{
Logger.Exception(ex);
}
return stream;
}
#endregion
メッセージを作成しようとすると:
WCallUpdate m_wCallUpdate = new WCallUpdate();
NotificationTypeKey m_notificationTypeKey = new NotificationTypeKey.Default;
CreateMessage(notificationTypeKey , wCallUpdate );
次のエラーが発生しました。
System.Runtime.Serialization.SerializationException: Type 'Xxx.DataContracts.WCall' in Assembly 'Xxx.DataContract, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
at Xxx.Notification.NotificationMessageFactory.CreateMessage(NotificationTypeKey notificationTypeKey, NotificationData notificationData) in Xxx.Notification\NotificationCenter.cs:line 36
Serializable フラグを前に置いてもDataContract
、問題は解決しません。
迅速な回答ありがとうございます。申し訳ありませんが、NotificationData のコードを入力するのを忘れていました (メインの投稿で編集)。
Serializable 属性を両方のクラスに入れてみましたが、成功しませんでした:(
#region NotificationData
/// <summary>
/// Basic class used in the notification service
/// </summary>
[Serializable]
[DataContract]
public class NotificationData
{
}
#endregion
と
[Serializable]
public class WCallUpdate : NotificationData
{
private string m_from = "";
[DataMember]
public string From
{
get { return m_from; }
set { m_from = value; }
}
private WCall m_wCall = new WCall();
[DataMember]
public WCall Call
{
get { return m_wCall; }
set { m_wCall = value; }
}
}
**編集: ** 結局のところ、罪悪感:) あなたは両方とも正しかった。[Serializable]
属性をすべての子クラスに広げるのを忘れていました。更新してコンパイルした後、例外が発生しなくなりました。あなたの正しい答えをありがとう:)
@Marc Gravel: 実際、私はあなたが提案していることについて考え、次の DataContractSerializer を作成しましたが、これが機能するかどうかわかりませんか? 私のクラスは他のクラスを使用していますか?DataContractSerializer の大きな問題は、シリアル化するオブジェクトの型を指定する必要があることです。私のクラスは他のクラスをプライベート フィールドとして使用しているため、問題が発生する可能性があります。
#region DataContractSerializer
/// <summary>
/// Creates a Data Contract Serializer for the provided type. The type must be marked with
/// the data contract attribute to be serialized successfully.
/// </summary>
/// <typeparam name="T">The type to be serialized</typeparam>
/// <returns>A data contract serializer</returns>
public static DataContractSerializer CreateDataContractSerializer<T>() where T : class
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
return serializer;
}
#endregion