Unity:从远程源解析 JSON 时出错

Posted

技术标签:

【中文标题】Unity:从远程源解析 JSON 时出错【英文标题】:Unity: Error Parsing JSON from Remote Source 【发布时间】:2016-08-06 04:24:14 【问题描述】:

在 Unity 5.4 中,我有一个 JSON 文件,当我从 StreamingAssets 本地获取它时,我可以通过 JsonUtility.FromJson 成功解析它,但通过 WWW 获取相同的文件当我从远程服务器获取它时抛出一个错误(ArgumentException: JSON parse error: Invalid value。)。

我可以在 JsonUtility 解析之前输出本地和远程 (jsonString) 文件,它们是相同的(我什至在 JSON 中验证了每个文件验证器。)

这是我用来检索和解析远程 JSON 的代码:

    void Prime()
    string url = "https:content_url.json";
    WWW www = new WWW(url);
    StartCoroutine(WaitForContentJSON(www));


IEnumerator WaitForContentJSON(WWW contentData)

    yield return contentData;

    // check for errors
    if (contentData.error == null)
    
        ParseJSON(contentData.text);

     else 
        Debug.Log("WWW Error: "+ contentData.error);
        


void ParseJSON(string jsonString)
    var ac = JsonUtility.FromJson<ArticlesCollection>(jsonString);

在调用 JsonUtility.FromJson

时会在 ParseJSON 内部抛出错误

非常感谢任何帮助。

编辑:根据@Programmer 的请求添加 JSON

通过File.ReadAllText从本地文件返回的JSON:


  "articles": [ 
    "articleID": "1",
    "title": "Life & Death at the Mexican Border",
    "byline": "Part 1 of Life and Death...",
    "longDescription": "Part 1 of Life and Death...",
    "imageURL": "http://foo.jpg",
    "videoURL": "http://foot.mp4",
    "sceneAssetBundle": "scene_bundle_1",
    "sceneName": "scene_1",
    "featured": true,
        "duration": "7:12",
        "videoSize": "625"
  , 
    "articleID": "2",
    "title": "Lake Mead",
    "byline": "The shrinking water....",
    "longDescription": "Welcome...",
    "imageURL": "http://vfoo.jpg",
    "videoURL": "http://food.mp4",
    "sceneAssetBundle": "scene_bundle_2",
    "sceneName": "scene_2",
    "featured": true,
        "duration": "1:45",
        "videoSize": "151"
  , 
    "articleID": "3",
    "title": "Visi...",
    "byline": "Experience...",
    "longDescription": "Experience...",
    "imageURL": "http://foo.jpg",
    "videoURL": "http://foo.mp4",
    "sceneAssetBundle": "scene_bundle_2",
    "sceneName": "scene_2",
    "featured": false,
        "duration": "5:46",
        "videoSize": "478"
   ]

从远程 (S3) 返回的 JSON:


  "articles": [ 
    "articleID": "1",
    "title": "Life & Death at...",
    "byline": "Part 1 of...",
    "imageURL": "http:foo.jpg",
    "videoURL": "http://foo.mp4",
    "featured": true,
        "duration": "7:12",
        "videoSize": "625"
  , 
    "articleID": "2",
    "title": "Lake Mead",
    "byline": "The...",
    "longDescription": "Welcome...",
    "imageURL": "http://foo.jpg",
    "videoURL": "http://foo.mp4",
    "featured": true,
        "duration": "1:45",
        "videoSize": "151"
  , 
    "articleID": "3",
    "title": "Visit",
    "byline": "Experience...",
    "longDescription": "Experience the...",
    "imageURL": "http:foo.jpg",
    "videoURL": "http://foo.mp4",
    "featured": false,
        "duration": "5:46",
        "videoSize": "478"
   ]

再次,我在验证器中验证了这两个 JSON 文件,当传递本地获取的 JSON 时,JsonUtility.FromJson 调用工作正常,但从远程源传递 JSON 时出错通过 WWW

获取

并且,根据@dbc 的请求,我将我的ArticlesCollectionArticles 包装类的主体发布到/against(?) 中,JSON 被解析。但同样,这在本地获取 JSON 时工作正常,所以我不怀疑这些文件中存在问题。

ArticlesCollection

using UnityEngine;

[System.Serializable]
public class ArticlesCollection

    public Article[] articles;

文章

using UnityEngine;

[System.Serializable]
public class Article

    public string title;
    public int articleID;
    public string byline;
    public string longDescription;
    public string imageURL;
    public string experienceURL;
    public bool featured;
    public string duration;
    public string experienceSize;

    public string sceneAssetBundle;
    public string sceneName;

【问题讨论】:

输入Debug.Log(jsonString) 然后在这里发布两个json数据。将它们标记为有效的 json 和无效的 json。同时发布ArticlesCollection的完整课程。这将有助于确定问题。 请分享您的 JSON。你的外部 JSON 容器是一个数组吗? IE。由[] 包围的以逗号分隔的值序列? (名称ArticlesCollection 暗示它是。)因为JsonUtility.FromJson 显然不支持数组。对于一些解决方法,请参阅 Unity C#: how to convert an Array of a class into JSON 或 Deserialization of JSON using MiniJSON in Unity C# @Programmer 感谢您的回复。我已将你们都要求的信息添加到帖子中。仅供参考,我发现了这个线程answers.unity3d.com/questions/844423/…,它表明 WWW.text 或远程获取过程的其他部分会在结果正文中添加额外的字节,并且使用 WWW.bytes 并切掉一些位可能是答案。 【参考方案1】:

由于您使用的是 Unity 5.4,因此您不应将 WWW 用于 Web 请求。 UnityWebRequest 替换了 WWW 并解决了 3 个额外字节的问题。使用它还有很多其他原因,例如支持 https。

IEnumerator WaitForRequest(string url)

    UnityWebRequest www = UnityWebRequest.Get(url);
    yield return www.Send();
    if (www.isError)
    
        Debug.Log("Error: " + www.error);
    
    else
    
        Debug.Log("Downloaded: " + www.downloadHandler.text);
        // byte[] results = www.downloadHandler.data;

        ArticlesCollection article = JsonUtility.FromJson<ArticlesCollection>(www.downloadHandler.text);
    

【讨论】:

感谢程序员。 UnityWebRequest 看起来比旧的 WWW 类更好的实现,但它以同样的方式抛出相同的错误 :( 猜猜我会坚持我的字节切割黑客并在下次我需要获取一些东西时探索 UnityWebRequest。谢谢你让我进入新的真棒。 我相信 UnityWebRequest 解决了这个问题。您也可以使用www.downloadHandler.data。不客气。 @Programmer 在我的例子中,var player = JsonHelper.FromJson&lt;Player&gt;(www.downloadHandler.text);www.downloadHandler.text 具有此值"user":"luzan@gmail.com","token":"tokenvalue" 时返回 null 您的 json 不是数组,因此您不需要使用 JsonHelper 类。只需使用JsonUtility.FromJson。另外,粘贴该 json here 以查看您的 json 类应该是什么样子。 好的,谢谢。在我删除 get;设置;。【参考方案2】:

所以答案正如这篇文章中指出的那样,http://answers.unity3d.com/questions/844423/wwwtext-not-reading-utf-8-text.html

这是针对我的问题的经过验证的修复。

问题似乎是响应的头部正好有 3 个额外的字节。解决方法是使用 WWW.bytes 而不是 WWW.text,然后切掉额外的 3 个字节。因此,

string jsonString;
jsonString = System.Text.Encoding.UTF8.GetString(contentData.bytes, 3, contentData.bytes.Length - 3);

考虑到我能找到的所有文档都使用 WWW.text 表示,这特别奇怪。似乎 Unity 应该向 WWW 添加一个数据属性来解决这个问题。

【讨论】:

WWW 现在被新的东西取代了。检查我的答案。

以上是关于Unity:从远程源解析 JSON 时出错的主要内容,如果未能解决你的问题,请参考以下文章

Spotify API:使用 Python 通过 JSON 解析时出错

在 asp.net mvc 登录项目中解析 json 时出错

解析 JSON 时出错:输入中有多个文档(Redshift 到 Snowflake SQL)

json解析时出错

解析 JSON 时出错

使用 Newtonsoft.Json 解析 JSON 时出错