1
votes

Erreur de désérialisation de la chaîne dans l'objet JSON

J'ai un fichier php qui lit un fichier .txt et l'envoie via un serveur php vers un script c # unity. Voici un extrait du fichier texte montrant les 3 premières lignes:

JsonReaderException: Unexpected character encountered while parsing value: . Path '', line 0, position 0.

Voici le script php:

public string lemma { get; set; } 
public string gloss { get; set; }

public GameDatabase(string lemma, string gloss)
{
    this.lemma = lemma;
    this.gloss = gloss;
}

public  ArrayList GetWords(string[] lines)
{
    foreach (string line in lines)
    {

        GameDatabase gd = JsonConvert.DeserializeObject<GameDatabase>(line);
        lemmasAndGlossesList.Add(new GameDatabase(gd.lemma, gd.gloss));
    }

    foreach(GameDatabase line in lemmasAndGlossesList)
    {
        Debug.Log(line.lemma + "------" + line.gloss);
    }

    return lemmasAndGlossesList;
}

Dans le script ac # , le texte est renvoyé et chaque ligne est séparée en un emplacement de tableau (chaîne [] lignes) comme ci-dessous:

IEnumerator GetTextFromFile()
    {
        bool succcessful = true;
        WWWForm form = new WWWForm();
        WWW www = new WWW("http://localhost:9000/tounity.php", form);

        yield return www;

        if(www.error != null)
        {
            succcessful = false;
        }
        else
        {
            succcessful = true;
        }

        if (succcessful)
        {
            populateWordList(www.text);
        }
    }

 void populateWordList(string text)
    {
        string[] textArray = text.Split('\n');
        wordsList = gameDatabase.GetWords(textArray);
    }

Le tableau est ensuite passé à une méthode qui désérialise ligne dans un objet de classe GameDatabase comme indiqué dans l'image ci-dessous:

<?php
$file = fopen("lemmas.txt", "r");
echo fread($file, filesize("lemmas.txt"));
fclose($file);
?>

L'erreur se produit dans GameDatabase gd = JsonConvert.DeserializeObject (ligne); et renvoie

{ "lemma" : "aljotta", "gloss" : "Fisħ soup" }
{ "lemma" : "arguzin", "gloss" : "Slave driver" }
{ "lemma" : "armunjaka", "gloss" : "Armunjaka" }

J'ai fait une recherche approfondie, cependant, je n'ai rien trouvé qui fonctionne. Toute aide serait grandement appréciée. Il est à noter que ce problème ne se produit pas lors du chargement du fichier texte directement dans unity sans utiliser php.


EDIT


Lors de l'utilisation du débogueur vs, c'est la valeur de la ligne à désérialiser:

 entrez la description de l'image ici

Le visualiseur JSON de Visual Studio 2019 signale cependant ceci:

 entrez la description de l'image ici

p >


8 commentaires

Votre JSON a l'air bien (tant que vous lisez ligne par ligne. Les caractères de saut de ligne habituels sont: \ r \ n . \ r . Avant de désérialiser la ligne , appelez: line = line.Trim ('\ r') .


@bassxzero Il traite chaque ligne séparément. Chaque ligne est un JSON valide.


J'ai essayé line.Trim ('\ r') mais cela ne fonctionne pas. J'ai également essayé d'ajouter des crochets au JSON qui ne fonctionnait pas et j'ai testé mon json dans jsonlint.com qui a renvoyé un json valide.


Comme je l'ai dit, essayer le même fichier sans l'envoyer via php et lire directement à l'aide d'un flux en c # fonctionne. Se pourrait-il que je doive passer des en-têtes avec mon PHP?


Y a-t-il une nouvelle ligne à la fin du fichier ou des nouvelles lignes supplémentaires dans www.Text ? Vous obtenez peut-être une entrée vide lorsque vous vous divisez sur \ n ... Essayez d'imprimer, ou d'examiner dans le débogueur, la valeur de ligne ou regardez simplement la longueur de la ligne par rapport au nombre de lignes que vous avez le fichier


J'ai édité mon message pour inclure des captures d'écran du débogueur @JonathonK


Y a-t-il un marqueur UTF-8 sur le fichier? Il ne s'imprime pas ... Qu'obtenez-vous si vous imprimez la ligne [0] ou si vous convertissez la chaîne en hexadécimal comme cette réponse stackoverflow.com/a/16999640/8723329


Voici la valeur hexadécimale que j'obtiens: EFBBBF7B20226C656D6D6122203A2022617267757A696E222C2022676C6F‌ 737322203A2022536C61‌ 76652064726976657222‌ 207D Notez que j'ai supprimé les tirets comme indiqué dans l'exemple que vous avez envoyé. Le fichier est au format utf-8 et j'ai également essayé de spécifier manuellement l'en-tête du fichier php en tant que texte / html, texte / plain. Malheureusement, j'ai besoin d'utf 8 car certains caractères dont j'ai besoin n'ont pas d'encodage utf 8


3 Réponses :


0
votes

Je ne connais pas le sintax c # mais cela fonctionnera.

modifiez votre fichier JSON.

for (GameDatabase line in JsonConvert.DeserializeObject<GameDatabase[]>(www.text)){
    Debug.Log(line.lemma + "------" + line.gloss);
}

appliquez JsonConvert.DeserializeObject à www.text

[
    { "lemma" : "aljotta", "gloss" : "Fisħ soup" },
    { "lemma" : "arguzin", "gloss" : "Slave driver" },
    { "lemma" : "armunjaka", "gloss" : "Armunjaka" }
]

Peut-être que ma syntaxe c # est erronée mais je voudrais que vous compreniez mon idée


1 commentaires

Pas d'Utilisation. J'ai le même problème qu'avant. Mon json est correct car je lis ligne par ligne plutôt que de lire tout le fichier texte à la fois.



0
votes

Je pense qu'il est possible que vous vous trompiez de désérialisation en utilisant JsonConvert.

À la place, lisez cette documentation et essayez d'utiliser les fonctions Unity: https://docs.unity3d.com/Manual/JSONSerialization.html

Pour commencer, vous ne définissez pas correctement le lemme et le gloss si vous souhaitez les utiliser pour désérialiser JSON dans Unity. Voir cette réponse pour plus d'informations: Sérialiser et désérialiser Json et Json Array dans Unity < / p>


0 commentaires

3
votes

Grâce au commentaire de Jonathon K et à votre réponse, nous pouvons voir les données renvoyées par le script PHP démarre avec une nomenclature : les trois premiers octets. Ce bel article explique comment gérer correctement ces données. En bref: utilisez un StreamReader pour lire les données.

Ce petit programme montre comment il pourrait fonctionner avec vos données:

{ "lemma" : "arguzin", "gloss" : "Slave driver" }
arguzin

Résultat:

using System;
using Newtonsoft.Json;
using System.IO;


public class Program
{
    public static void Main()
    {
        var bytes = new byte[] {
            0xEF,0xBB,0xBF,0x7B,0x20,0x22,0x6C,0x65,0x6D,0x6D,0x61,0x22,
            0x20,0x3A,0x20,0x22,0x61,0x72,0x67,0x75,0x7A,0x69,0x6E,0x22,
            0x2C,0x20,0x22,0x67,0x6C,0x6F,0x73,0x73,0x22,0x20,0x3A,0x20,
            0x22,0x53,0x6C,0x61,0x76,0x65,0x20,0x64,0x72,0x69,0x76,0x65,
            0x72,0x22,0x20,0x7D};

        string json;
        using(var ms = new MemoryStream(bytes))
        using(var sr = new StreamReader(ms))
        {
            json = sr.ReadToEnd();
            Console.WriteLine(json);
        }

        // I'm using dynamic here. In your case you can use GameDatabase
        dynamic obj = JsonConvert.DeserializeObject(json);
        Console.WriteLine(obj.lemma);
    }
}


0 commentaires