Laden...

JSON deserialiserung schlägt fehl "Ungültiger JSON-Primitiv"

Erstellt von C3PO vor 6 Jahren Letzter Beitrag vor 6 Jahren 4.392 Views
C3PO Themenstarter:in
6 Beiträge seit 2015
vor 6 Jahren
JSON deserialiserung schlägt fehl "Ungültiger JSON-Primitiv"

Hallo zusammen,

bei einem meiner Projekte möchte ich eine einfache Klasse mittels JavaScriptSerializer serialisieren um gewisse Informationen zu speichern. Beim Programmstart (bzw. beim initialisieren der DLL-Datei) sollen die gespeicherten Informationen wieder deserialisiert werden.

Dazu nutze ich folgenden Code:

public List<Quote> Quotes = new List<Quote>();
private string configFile;
public void Init()
        {
            // Define config file
            configFile = PluginInfoDevice.ClientConfig.GetSaveFolder() + Path.DirectorySeparatorChar + "twbi_Quotes.conf";

            // Load all quotes into List<>
            if (File.Exists(configFile))
            {
                // Create new JavaScriptSerializer object
                var jss = new JavaScriptSerializer();

                // Deserialize file
                Quotes = jss.Deserialize<List<Quote>>(configFile);
            }
            else
            {
                // No config file has been found. Try to generate a empty one.
                // Create new JavaScriptSerializer object
                var jss = new JavaScriptSerializer();

                try
                {
                    // Add an example Quote.
                    Quotes.Add(new Quote(0, "Albert Einstein", "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe.", "#twbi"));
                    
                    // Serialize Class and write data to file.
                    System.IO.File.WriteAllText(configFile, jss.Serialize(Quotes));

                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("*** twbi_Quotes: Cannot find configuration file. The default file has been created.");
                    Console.WriteLine("*** twbi_Quotes: {0})", configFile);
                    Console.ResetColor();
                }
                catch (Exception ex)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("*** twbi_Quotes: Cannot find configuration file. Also writing a new file has failed");
                    Console.WriteLine("*** twbi_Quotes: {0})", configFile);
                    Console.WriteLine("*** twbi_Quotes: {0}", ex.Message);
                    Console.ResetColor();
                }
            }
        }

Die entsprechende Klasse "Quote" sieht wie folgt aus:

public class Quote
    {
        public int id { get; set; }
        public string Author { get; set; }
        public string Message { get; set; }
        public string Channel { get; set; }
        public DateTime DateTimeUTC { get; set; }

        public Quote()
        {

        }
        public Quote(int id, string Author, string Message, string Channel)
        {
            this.id = id;
            this.Author = Author;
            this.Message = Message;
            this.Channel = Channel;
            this.DateTimeUTC = DateTime.Now.ToUniversalTime();
        }
    }

Wenn die Datei, in der List<Quote> serialisiert werden soll nicht exisiert, wird sie automatisch erstell und der Beispiel-Eintrag in die Datei geschrieben. Soweit klappt das auch alles ganz gut.
Wenn ich das Programm beende und neu starte und ich nun die vorhandene Datei deserialisieren möchte, erhalte ich den Fehler: > Fehlermeldung:

Ungültiger JSON-Primitiv: C.

Ich kann mir ehrlich gesagt nicht erklären, wo mein Fehler liegt. Ich nutze die selbe Methode (nur in statischen Methoden verpackt) in anderen Projekten und da funktioniert das einwandfrei. Ich hoffe, ihr könnt mir weiterhelfen. 👍

Edit: Achja, so sieht die serialisierte Datei aus:

[{
		"id": 0,
		"Author": "Albert Einstein",
		"Message": "Two things are infinite: the universe and human stupidity; and I\u0027m not sure about the universe.",
		"Channel": "#twbi",
		"DateTimeUTC": "\/Date(1493324922889)\/"
	}
]

16.834 Beiträge seit 2008
vor 6 Jahren

Klassischer Fehler, den man binnen 2 Minuten Debugging selbst finden kann 😉
[Artikel] Debugger: Wie verwende ich den von Visual Studio?

Du versuchst nicht den Inhalt der Datei zu deserialisieren, sondern den Pfad.
Dein Pfad beginnt wohl mit "C" da vermutlich "C:....." und ergo: Invalid Primitive "C", da eine JSON nie mit einem Zeichen C beginnen kann.

Pfade kombiniert man übrigens mit Path.Combine().

PS: nimm lieber NewtonSoft.Json.
Der JavaScriptSerializer ist ziemlicher Käse - und hat eine desaströse Performance.

C3PO Themenstarter:in
6 Beiträge seit 2015
vor 6 Jahren

Ahh... Jetzt seh ich es. Da war ich wohl blind! Vielen Dank!

PS, der Debugger hilft mir in diesem Fall nicht viel, da dieser Code zu einer Bibliothek und nicht zu einer ausführbaren EXE gehört. Ich lasse mir lediglich im Host-Prozess die Exception ausgeben.

PS.: Ich bleibe mit Absicht bei den Boardmitteln des .NET-Frameworks. Das erleichtert die kompatibilität des Programmes. Auch in Bezug auf MONO. Davon abgesehen lädt der JavaScriptSerializer nur ein einziges mal pro Programmstart und es sind keine zig MB an Daten zu erwarten.

16.834 Beiträge seit 2008
vor 6 Jahren

Der Debugger funktioniert auch auf Klassenbibliotheken.

PS.: Ich bleibe mit Absicht bei den Boardmitteln des .NET-Frameworks.

Damit wirst Du nicht (mehr) weit kommen.
Selbst Microsoft vertraut in vielen Bereichen mehr den Open Source Projekten. So ist NewtonSoft.Json nicht nur das meist gelade NuGet Paket überhaupt (über 55 Milllionen Downloads) sondern auch seit längerem Standard in jedem Webprojekt und nicht mehr der JavaScriptSerializer.

Mono ist sowieso spätestens seit .NET Core obsolet.

16.834 Beiträge seit 2008
vor 6 Jahren

...übrigens lohnt sich ein Blick in Mono. Man sollte schon wissen, was man nutzt, bevor man blind Nein sagt 😉

Die Mono Implementierung ist nichts anderes als ein Wrapper für NewtonSoft.Json.
Kann man sich also locker sparen.