【问题标题】:Error deserialising string into JSON object将字符串反序列化为 JSON 对象时出错
【发布时间】:2019-09-14 15:51:03
【问题描述】:

我有一个 php 文件,它读取 .txt 文件并通过 php 服务器将其发送到 c# unity 脚本。下面是显示前 3 行的文本文件的 sn-p:

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

这是 php 脚本:

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

在 c# 脚本中,文本被返回,每一行被分隔成一个数组(string[] 行)槽,如下所示:

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);
    }

然后将数组传递给一个方法,该方法将每一行反序列化为 GameDatabase 类的对象,如下图所示:

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;
}

错误发生在GameDatabase gd = JsonConvert.DeserializeObject&lt;GameDatabase&gt;(line);并返回

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

我进行了广泛的搜索,但没有找到任何有效的方法。任何帮助将不胜感激。值得注意的是,不使用php直接将文本文件加载到unity时不会出现这个问题。


编辑


使用 vs 调试器时,这是要反序列化的行中的值:

Visual Studio 2019 的 JSON 可视化工具报告了这一点:

【问题讨论】:

  • 你的 JSON 看起来不错(只要你逐行阅读。通常的换行符是:\r\n。你只是在 \n 上拆分,留下剩余的 \r。在你之前反序列化line 调用:line = line.Trim('\r')
  • @bassxzero 他单独处理每一行。每行都是一个有效的 JSON。
  • 我试过 line.Trim('\r') 但这不起作用。我还尝试在无效的 JSON 中添加方括号,并在 jsonlint.com 中测试了我的 json,它返回了有效的 json。
  • 正如我所说,尝试相同的文件而不通过 php 发送它并直接使用 c# 中的流进行读取。难道是我需要用我的 php 传递任何标题?
  • 文件末尾是否有换行符,或者www.Text 中是否有任何额外的换行符?当您在 \n 上拆分时,您可能会得到一个空条目...尝试打印或在调试器中检查 line 的值,或者只查看与您拥有文件的行数相比的行长

标签: c# php json unity3d json.net


【解决方案1】:

感谢 Jonathon K 的评论和您的回复,我们可以看到 PHP 脚本返回的数据以 with a BOM 开头:前三个字节。 This nice article 解释了如何正确处理此类数据。简而言之:使用StreamReader 读取数据。

这个小程序演示了它如何处理您的数据:

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);
    }
}

输出:

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

【讨论】:

    【解决方案2】:

    我不知道 c# sintax,但这会起作用。

    更改您的 JSON 文件。

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

    申请JsonConvert.DeserializeObjectwww.text

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

    也许我的 c# 语法是错误的,但我希望你能理解我的想法

    【讨论】:

    • 没用。我遇到和以前一样的问题。我的 json 是正确的,因为我是逐行读取而不是一次读取整个文本文件。
    【解决方案3】:

    我认为您使用 JsonConvert 进行反序列化可能会出错。

    相反,请阅读此文档并尝试使用 Unity 函数: https://docs.unity3d.com/Manual/JSONSerialization.html

    对于初学者,如果您希望在 Unity 中使用它们来反序列化 JSON,那么您定义的引理和光泽度不正确。有关更多信息,请参阅此答案: Serialize and Deserialize Json and Json Array in Unity

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-04
      • 2020-02-03
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      • 2012-07-18
      相关资源
      最近更新 更多