Serialisierung in C# mit einer abgeleiteten Klasse
Baue ich eine Benachrichtigung Rahmen und dafür bin ich serialisieren und Deserialisieren eine Basisklasse, von der alle Klassen, die ich senden möchten, ableiten.
Das problem ist, dass der code kompiliert, aber wenn ich tatsächlich versuchen zu serialisieren Sie dieses basic-Klasse bekomme ich einen Fehler sagen
System.- Laufzeit.Serialisierung.SerializationException: Der Typ 'Xxx.DataContracts.WQAllocationUpdate' in Assembly 'Xxx.DataContract, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null " ist nicht als serialisierbar markiert.
Hier ist der code :
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; }
}
}
Den DataContract
für die Benachrichtigung:
///<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,
}
Code zum serialisieren der Daten ist:
#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
Wenn ich versuche, um eine Nachricht zu erstellen:
WCallUpdate m_wCallUpdate = new WCallUpdate();
NotificationTypeKey m_notificationTypeKey = new NotificationTypeKey.Default;
CreateMessage(notificationTypeKey , wCallUpdate );
Bekam ich die folgende Fehlermeldung:
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
Wenn ich das Serializable-flag vor der DataContract
man das problem nicht lösen.
danke für die schnelle Antwort.
Sorry, dass ich vergessen habe, den code der NotificationData (bearbeitet in der main-post)
Ich versucht, indem Sie das Serializable-Attribut, um sowohl Klasse-ohne Erfolg 🙁
#region NotificationData
///<summary>
///Basic class used in the notification service
///</summary>
[Serializable]
[DataContract]
public class NotificationData
{
}
#endregion
und
[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; }
}
}
**Edit: * Mea culpa doch 🙂 Sie waren beide Recht.
Ich vergaß zu verbreiten [Serializable]
- Attribut für alle die Kind-Klasse.
Nach der Aktualisierung und Zusammenstellung, ich habe nicht mehr die Ausnahme.
ich danke Ihnen beiden für Ihre Antworten zu korrigieren 🙂
@Marc Kies:
Eigentlich dachte ich über das, was Sie vorschlagen, und erstellt die folgenden DataContractSerializer, aber ich bin mir nicht sicher, ob dies funktionieren wird? Als meine Klassen nutzen andere Klassen? das große problem mit der DataContractSerializer ist, dass Sie brauchen, um zu geben Sie den Typ des Objekts, das Sie serialisieren möchten, und als meine Klasse andere Klasse, als die privaten Felder, die verursachen könnten ein problem genau?
#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
InformationsquelleAutor srodriguez | 2009-04-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
[Serializable] an der Spitze der Klasse. Serializable ist nicht unbedingt übernommen AFAIK. also selbst wenn der Basis-Klasse [Serializable], müssen Sie noch auf die abgeleitete Klasse.
InformationsquelleAutor Darren Kopp
Ich bin sehr verwirrt, warum bist du mit
BinaryFormatter
mit einem Daten-Vertrag. Wäre es normal zu benutzenDataContractSerializer
hier... die Logik ist dann ähnlich wie mit[Serializable]
, außer Sie müssen[DataContract
], und es serialisiert die Nominierten ([DataMember]
) Mitglieder, anstatt die Felder, dieBinaryFormatter
arbeitet.Tatsächlich, für viele Gründe ( wie Sprödigkeit ), würde ich vorschlagen, den Wechsel zu
DataContractSerializer
, vor allem da zu sein scheint, dass Ihre Absicht. Oder wenn Sie wollen eine kompakte binäre form, protobuf-net hilfreich sein kann (plus Portierbarkeit zwischen den Plattformen, auch).Wie nebenbei - Sie brauchen nicht die
[DataContract]
aufenum
s - es schadet nicht, aber bringt nicht viel.InformationsquelleAutor Marc Gravell
Um eine Klasse serialisierbar sein, markieren Sie es mit dem serializable-Attribut oder es abgeleitet von MarshalByRefObject abgeleitet.
Ableitung von NotificationData, ist es dann serialisierbar?
Prüfen Sie auch, das: bei serializable Klassen-Daten werden in einer Baugruppe überprüfen Sie Ihre Projekt-oder Datei-Referenz in Visual Studio, um sicherzustellen, dass Sie erhalten die richtige.
Auch wenn Sie sich die Montage-und legen Sie es in den GAC, werden Sie sicher, dass die assembly im GAC ist das richtige! Ich habe festgestellt viele zeitaufwändige debugsessions, weil ich aktualisiert die Montage von version 1.0.0.0 auf 1.0.0.1 und vergessen den alten zu ersetzen, in der GAC. Assemblys im GAC geladen werden, bevor die lokalen Versammlungen, in Erinnerung behalten. Und... binäre Formatierung ist sehr streng bezüglich der Montage Versionen.
InformationsquelleAutor Patrick Peters
Habe ich eine Klasse angelegt XList, dies zu erreichen:
Mehr details finden Sie hier.
InformationsquelleAutor David