DataException beim Deserialisieren

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von DerLeiharbeiter.

    DataException beim Deserialisieren

    Guten Morgen allerseits,

    als Neuling hier möchte ich mich kurz vorstellen: Ich bin der Christopher und als Softwareentwickler in einem Konzern tätig.

    So, und nun gleich zu meinem Problem. Ich bekomme, wenn ich eine Datei zu einem Objekt deserialisieren möchte, folgende Exception:

    TargetInvocationException: "Ein Aufrufziel hat einen Ausnahmefehler verursacht."
    bei System.RuntimeMethodHandle._SerializationInvoke(IRuntimeMethodInfo method, Object target, SignatureStruct& declaringTypeSig, SerializationInfo info, StreamingContext context)
    bei System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)
    bei System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)
    bei System.Runtime.Serialization.ObjectManager.DoFixups()
    bei System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
    bei System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
    bei System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
    bei ETAuswertung.Serialization.Deserialize(Byte[] Data) in C:\01_DATA\ETAuswertung\Quellcode\ETAuswertung\Serialization.vb:Zeile 18.
    bei ETAuswertung.frmMainWindow.mniLoadPackaage_Click(Object sender, EventArgs e) in C:\01_DATA\ETAuswertung\Quellcode\ETAuswertung\frmMainWindow.vb:Zeile 350.
    bei System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
    bei System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
    bei System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
    bei System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
    bei System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
    bei System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
    bei System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
    bei System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
    bei System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    bei System.Windows.Forms.Control.WndProc(Message& m)
    bei System.Windows.Forms.ScrollableControl.WndProc(Message& m)
    bei System.Windows.Forms.ToolStrip.WndProc(Message& m)
    bei System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
    bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
    bei ETAuswertung.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:Zeile 81.
    bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
    bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
    bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    bei System.Threading.ThreadHelper.ThreadStart()

    Dabei ist folgende InnerException aufgetreten:

    DataException: Undefinierter Datentyp: ''.
    bei System.Data.XSDSchema.XsdtoClr(String xsdTypeName)
    bei System.Data.Common.ObjectStorage.ConvertXmlToObject(XmlReader xmlReader, XmlRootAttribute xmlAttrib)
    bei System.Data.XmlDataLoader.LoadColumn(DataColumn column, Object[] foundColumns)
    bei System.Data.XmlDataLoader.LoadTable(DataTable table, Boolean isNested)
    bei System.Data.XmlDataLoader.LoadData(XmlReader reader)
    bei System.Data.DataSet.ReadXmlDiffgram(XmlReader reader)
    bei System.Data.DataSet.ReadXml(XmlReader reader, XmlReadMode mode, Boolean denyResolving)
    bei System.Data.DataSet.DeserializeDataSetData(SerializationInfo info, StreamingContext context, SerializationFormat remotingFormat)
    bei System.Data.DataSet.GetSerializationData(SerializationInfo info, StreamingContext context)
    bei ETAuswertung.ClientDataSet..ctor(SerializationInfo info, StreamingContext context) in C:\01_DATA\ETAuswertung\Quellcode\ETAuswertung\Package\ClientDataSet.Designer.vb:Zeile 93.

    Der Programmteil, in dem der Fehler auftritt:

    VB.NET-Quellcode

    1. Public Shared Function Deserialize(Data As Byte()) As Object
    2. Dim ms As New MemoryStream(Data)
    3. Dim formatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
    4. Dim instance As Object = formatter.Deserialize(ms) 'Zeile, in der die Exception auftritt.
    5. ms.Close()
    6. Return instance
    7. End Function


    Das Serialisieren funktioniert einwandfrei, wenn ich das Objekt danach wieder deserialisieren möchte, schmeißt es den Fehler. Ich hab schon ohne Ende Google bemüht, weiß aber immer noch nicht, was eigentlich los ist.


    Ich programmiere mit Visual Studio 2010 Professional und .net-Framework 4.0.

    Vielen Dank und viele Grüße

    Christopher

    DerLeiharbeiter schrieb:

    VB.NET-Quellcode

    1. Dim instance As Object
    Mach da mal
    Dim instance As MyObject draus, damit er weiß, was das für ein Objekt ist.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    hat glaub nix damit zu tun.
    Ich denk, entweder sind die Daten falsch oder das Objekt hat bei der Serialisierung Mist gebaut. (Also entweder sind die Daten falsch, oder die Daten sind falsch ;))

    Den ganzen Überblick hat man also erst, wenn man Serialisierung und Deserialisierung zusammen angugge kann.

    Dazu Bitte VB-Tag benutzen - aber richtig
    Hi
    sollte kein Problem sein. Von welchem Typ sind außerdem die Daten und wie ist der Typ und von dir definierte, intern verwendete Typen beschaffen?
    Btw. wäre es nicht sinnvoller, Data As IO.Stream zu definieren und ggf. bei der Übergabe einen MemoryStream um ein Byte-Array zu legen, sofern das dann überhaupt noch nötig ist? Es gibt auch System.IO.FileStream.

    Gruß
    ~blaze~

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „~blaze~“ ()

    Guten Morgen,

    hier ist mal die komplette Klasse zur Serialisierung:

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class Serialization
    3. Public Shared Function Serialize(Instance As Object) As Byte()
    4. Dim ms As New MemoryStream()
    5. Dim bw As New BinaryWriter(ms)
    6. Dim formatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
    7. formatter.Serialize(bw.BaseStream, Instance)
    8. bw.Close()
    9. Return ms.ToArray()
    10. End Function
    11. Public Shared Function Deserialize(Data As Byte()) As Object
    12. Dim ms As New MemoryStream(Data)
    13. Dim formatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
    14. Dim instance As Object = formatter.Deserialize(ms)
    15. ms.Close()
    16. Return instance
    17. End Function
    18. End Class


    Sie ist bewusst einfach gehalten, denn ich wollte mir die Möglichkeit offen halten, auch andere Dinge zu serialisieren. Außerdem wird diese Klasse auch in anderen Programmen hier benutzt und dort funktionieren die Methoden einwandfrei.

    Aufgerufen wird die Serialisierung hier:

    VB.NET-Quellcode

    1. Private Sub mniSavePackage_Click(sender As System.Object, e As System.EventArgs) Handles mniSavePackage.Click
    2. Try
    3. Dim sfd As New SaveFileDialog
    4. If sfd.ShowDialog = Windows.Forms.DialogResult.Cancel Then
    5. Exit Sub
    6. End If
    7. Dim packageBytes As Byte() = Serialization.Serialize(_Package)
    8. File.WriteAllBytes(sfd.FileName, packageBytes)
    9. MessageBox.Show(MainWindowTexts.PackageSaved, MainWindowTexts.messageHeaderSaved, MessageBoxButtons.OK, MessageBoxIcon.Information)
    10. Catch ex As Exception
    11. MessageBox.Show(ex.Message, MainWindowTexts.messageHeaderError, MessageBoxButtons.OK, MessageBoxIcon.Error)
    12. End Try
    13. End Sub


    Das entsprechende Gegenstück (gekürzt, da es vertrauliche Sachen enthält):

    VB.NET-Quellcode

    1. Dim ofd As New OpenFileDialog
    2. ofd.Multiselect = False
    3. If ofd.ShowDialog = Windows.Forms.DialogResult.Cancel Then
    4. Exit Sub
    5. End If
    6. Dim br As New BinaryReader(File.Open(ofd.FileName, FileMode.Open))
    7. Dim countBytes As Integer = CInt(br.BaseStream.Length)
    8. _Package = CType(Serialization.Deserialize(br.ReadBytes(countBytes)), Clientpackage)


    _Package ist die Basisklasse PackageBase2, von der sich zwei Klassen ableiten. Davon wird eine mit Hilfe der Methoden serialisiert.

    In der Klasse PackageBase2 und in der abgeleiteten Klasse sind die als Eigenschaften zwei DataSets enthalten. Genaueres kann ich leider nicht über die Klassen sagen, da ich sonst Ärger mit meinem Chef bekommen würde.

    @~blaze~:
    Mit dem FileStream könnte ich das mal probieren. Dann könnte ich die Logik noch stärker drin kapseln. Momentan verarbeiten diese Methoden ja nur die Objekte zu Byte() und zurück.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DerLeiharbeiter“ ()

    anne Serialisiererei liegts vmtl. nicht, wie mein kleiner Test zeigt:

    VB.NET-Quellcode

    1. Dim values = {5, 1, 2, 7, 9, 0, 3, 6, 8}
    2. Dim bs = Serialize(values)
    3. Dim vals2 = Deserialize(bs)
    vals2 ist korrekt.
    (Trotzdem weiß ich nicht, was der BinaryWriter da inne Serialize verloren hat. Überhaupt ist der ganze Code Crap, am besten du lässt das Gewurstel mittm MemoryStream und den ByteArrays bleiben, und serialisierst direkt in den gewünschten FileStream)

    Also wird wohl iwelcher Mist in den Package-Klassen sich ereignen.

    Kennst du schon typisiertes Dataset?
    Häufig wird nämlich noch rumserialisiert, weil typDataset nicht bekannt ist.
    Edit by ErfinderDesRades: unnötiges Vollzitat entfernt

    Muss ich mal da sehen, was los ist. Ich verwende bereits zwei typisierte DataSets, eines in der Basisklasse, welche allgemeingültige Daten enthält, und eines in den erbenden, welches die speziellen Daten hat.

    Hab jetzt mal die Byte-Arrays ausgemistet und durch einen Filestream ersetzt. Sieht jetzt sauberer aus, aber der Fehler beim Deserialisieren bleibt bestehen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Servus miteinander,

    ich hab bisher den Fehler noch nicht gefunden, aber vielleicht einen Hinweis darauf. Ich möchte daher mal um Meinungen bitten, ob die Richtung stimmt oder ich weitersuchen dürfte.

    Im typisierten DataSet ist eine DataTable, in der eine Spalte vom Typ Object ist. In dieser Spalte wird ein Wert von einer Enumeration gespeichert. Als ich ein älteres Paket geladen habe, wo diese Spalte noch nicht vorhanden war, lief das Programm einwandfrei durch. Natürlich schmiss es dann später Fehler, da es dann auf die nicht vorhanden Spalte zugreifen wollte.

    Wenn ich aber den aktuellen Stand laden will, dann kommt wieder bekannte Fehler.

    Daher, ist es möglich, das die Enumeration in der Object-Spalte daran schuld ist?

    Viele Grüße
    Christopher
    Wenn Du solch Verdacht hast, mach Dir gezielt ein kleines Testobjekt, wo Du das untersuchen kannst.
    Probier mal, da ein Integer zu verwenden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo RodFromGermany,

    hab ich jetzt mal gemacht und der Verdacht hat sich dabei bestätigt. Der gleiche Fehler trat auch dort auf.

    Tja, dann möge der Umbau beginnen, das ist nämlich was größeres.

    Trotzdem vielen Dank an alle.

    Viele Grüße
    Christopher