Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Resolved Unexpected character encountered while parsing value: . Path '', line 0, position 0. Reading JSON

Discussion in 'Scripting' started by andresbvalenzuela, Nov 11, 2021.

  1. andresbvalenzuela

    andresbvalenzuela

    Joined:
    May 4, 2018
    Posts:
    3
    Hi, Unity with JsonReader from JSON.NET throws me an exception.

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

    The problem is, i checked multiple ways of parsing with classes, just dictionaries, and nothing.
    i'm using UnityWebRequest to get a PHP to echo me the JSON of all values from a Table, and i don't know what to do.

    JSON that the PHP Gives me:
    [{"deptoid":"101","piso":"1","disponible":"1"},{"deptoid":"102","piso":"1","disponible":"0"},{"deptoid":"201","piso":"2","disponible":"1"},{"deptoid":"301","piso":"3","disponible":"1"},{"deptoid":"401","piso":"4","disponible":"1"}]



    Code:
    Code (CSharp):
    1. public class Retrieval : MonoBehaviour
    2. {
    3.     //private string secretKey = "RitoLab$$";
    4.     public string DeptosURL =
    5.              "https://ritolab.cl/demounitydepartamentos/getdptos.php";
    6.     // Start is called before the first frame update
    7.     public void GetDptoBtn()
    8.     {
    9.     }
    10.  
    11.     void Start()
    12.     {
    13.         StartCoroutine("GetDpto");
    14.     }
    15.  
    16.     IEnumerator GetDpto()
    17.     {
    18.         UnityWebRequest hs_get = UnityWebRequest.Get(DeptosURL);
    19.         yield return hs_get.SendWebRequest();
    20. if (hs_get.error != null)
    21.         {
    22.             Debug.Log("Hubo un error Bajando informacion de los departamentos: " + hs_get.error);
    23.         }
    24.         else
    25.         {
    26.             string dataText = System.Text.Encoding.UTF8.GetString(hs_get.downloadHandler.data);
    27.             Debug.Log(dataText);
    28.             Rootobject departamentos = JsonConvert.DeserializeObject<Rootobject>(dataText);
    29. foreach (Class1 depto in departamentos.Property1)
    30.             {
    31.                 Debug.Log("Departamento 1: Piso: " + depto.piso + " DepartamentoID: " + depto.deptoid + " y Disponibilidad: " + depto.disponible);
    32.             }
    33.  
    34. [System.Serializable]
    35.     public class Rootobject
    36.     {
    37.         public Class1[] Property1 { get; set; }
    38.     }
    39.     [System.Serializable]
    40.     public class Class1
    41.     {
    42.         public string deptoid { get; set; }
    43.         public string piso { get; set; }
    44.         public string disponible { get; set; }
    45.     }
    I have read multiple threads and none gives me a solution to my problem, so i thought i would write this for Help.

    Thanks in advance.
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,890
    Unity's JSON parser cannot read "naked arrays" like you have. The way to solve this is to wrap the json array in a json object:
    Code (CSharp):
    1. {
    2.   "Property1":
    3.     [{"deptoid":"101","piso":"1","disponible":"1"},{"deptoid":"102","piso":"1","disponible":"0"},    {"deptoid":"201","piso":"2","disponible":"1"},{"deptoid":"301","piso":"3","disponible":"1"},    {"deptoid":"401","piso":"4","disponible":"1"}]
    4. }
    You can do this right in your code:
    Code (CSharp):
    1. dataText = "{\"Property1\": " + dataText + "}";
    EDIT: I misread your post a bit,. i see you're using Newtonsoft. Problem is your JSON doesn't match your object structure. The code I posted here will change the JSON structure to match your class structure.
     
    Last edited: Nov 11, 2021
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    Adding onto what Praetor says above, beware of this:

    Problems with Unity "tiny lite" built-in JSON:

    In general I highly suggest staying away from Unity's JSON "tiny lite" package. It's really not very capable at all and will silently fail on very common data structures, such as Dictionaries and Hashes and ALL properties.

    Instead grab Newtonsoft JSON .NET off the asset store for free, or else install it from the Unity Package Manager (Window -> Package Manager).

    https://forum.unity.com/threads/jso...-not-working-as-expected.722783/#post-4824743

    https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347

    Also, always be sure to leverage sites like:

    https://jsonlint.com
    https://json2csharp.com
    https://csharp2json.io

    PS: for folks howling about how NewtonSoft JSON .NET will "add too much size" to your game, JSON .NET is like 307k in size, and it has the important advantage that it actually works the way you expect a JSON serializer to work in the year 2021.
     
  4. andresbvalenzuela

    andresbvalenzuela

    Joined:
    May 4, 2018
    Posts:
    3
    I actually used in the code the Newtonsoft JSON.NET, in the actual script i have newtonsoft namespace inserted, i must've not copied it though.
    Thanks for the answers, I finally Resolved it by making a "fake JSON" i have the PHP give me the values separated by "_" and each row separated by "-" , so i used a class and split to get them and set them on the class, now it works flawlessly.
    PHP to Get new format of values:

    $sql = 'SELECT * FROM Depas';
    $statement = $pdo->prepare($sql);
    $statement->execute();
    $results = $statement->fetchAll(PDO::FETCH_ASSOC);
    foreach($results as $row)
    {
    echo $row['piso']. "_";
    echo $row['deptoid']. "_";
    echo $row['disponible']. "-";
    }


    And i get this:
    1_101_1-1_102_0-2_201_1-3_301_1-4_401_1-


    so i do this to split them, delete the last one since it gives an extra "-"

    C#:
    Code (CSharp):
    1. public class Retrieval : MonoBehaviour
    2. {
    3. public string DeptosURL =
    4.              "https://ritolab.cl/demounitydepartamentos/getdptos.php";
    5.     public String[] textSplit;
    6.     public List<Departamento> Departamentos = new List<Departamento>();
    7.  
    8.     void Start()
    9.     {
    10.         StartCoroutine("GetDpto");
    11.     }
    12.  
    13.     IEnumerator GetDpto()
    14.     {
    15.         UnityWebRequest hs_get = UnityWebRequest.Get(DeptosURL);
    16.         yield return hs_get.SendWebRequest();
    17.         if (hs_get.error != null)
    18.         {
    19.             Debug.Log("Hubo un error Bajando informacion de los departamentos: " + hs_get.error);
    20.         }
    21.         else
    22.         {
    23.             string dataText = System.Text.Encoding.UTF8.GetString(hs_get.downloadHandler.data);
    24.             Debug.Log(dataText); // For Debugging Raw Text
    25.             textSplit = dataText.Split('-'); // To make an array with all rows encapsulated
    26.             Array.Resize(ref textSplit, textSplit.Length - 1); //to delete the last one, since it's empty due to formatting in php.
    27.             for(int i = 0; i < textSplit.Length-1; i++)
    28.             {
    29.                 String[] textSplit2 = textSplit[i].Split('_'); //to split each one into an array of single values, then i assign them to a new class inside a list.
    30.                 Departamento depa = new Departamento();
    31.                 depa.piso = textSplit2[0];
    32.                 depa.deptoid = textSplit2[1];
    33.                 depa.disponible = textSplit2[2];
    34.                 Departamentos.Add(depa);
    35.             }
    36.             Debug.Log(Departamentos[0].deptoid);
    37.             Debug.Log(Departamentos[1].deptoid);
    38.             Debug.Log(Departamentos[2].deptoid);
    39.         }
    40.     }
    41.  
    42. public class Departamento
    43.     {
    44.         public string deptoid { get; set; }
    45.         public string piso { get; set; }
    46.         public string disponible { get; set; }
    47.     }