我是使用Json的新手,我无法弄清楚为什么数据没有反序列化。我尝试了很多事情,但不知道问题出在哪里。 首先,我需要从此链接https://jsonplaceholder.typicode.com/users获取数据 然后我需要反序列化它。 (需要使用REST请求)
每当我想使用任何属性时,它都会告诉我它的NULL“ NullReferenceException:对象引用未设置为对象的实例”
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Net;
using System.IO;
public class Houses : MonoBehaviour
{
public GameObject Prefab;
void Update()
{
if (Input.GetKey(KeyCode.T))
{
onClick();
}
}
public void onClick()
{
UnityWebRequest request = UnityWebRequest.Get("https://jsonplaceholder.typicode.com/users");
RootObject[] rootObjects = JsonUtility.FromJson<RootObject[]>(request.downloadHandler.text);
//Debug.Log(request.downloadHandler.text);
//foreach (var item in rootObjects)
//{
// Debug.Log(item.id);
//}
//----------------------------------------------------------------------------------------
//Latitude is the Y axis, longitude is the X axis
//for (int i = 0; i < rootObjects.Length; i++)
//{
// float x = float.Parse(rootObjects[i].address.geo.lng);
// float y = float.Parse(rootObjects[i].address.geo.lat);
// Instantiate(Prefab, new Vector3(x, y, 0f), Quaternion.identity);
//}
}
}
//public class ListItems
//{
// //public RootObject[] rootObjects;
//public List<RootObject> rootObjects;
//}
[System.Serializable]
public class Geo
{
public string lat { get; set; }
public string lng { get; set; }
}
[System.Serializable]
public class Address
{
public string street { get; set; }
public string suite { get; set; }
public string city { get; set; }
public string zipcode { get; set; }
public Geo geo { get; set; }
}
[System.Serializable]
public class Company
{
public string name { get; set; }
public string catchPhrase { get; set; }
public string bs { get; set; }
}
[System.Serializable]
public class RootObject
{
public int id; //{ get; set; }
public string name { get; set; }
public string username { get; set; }
public string email { get; set; }
public Address address { get; set; }
public string phone { get; set; }
public string website { get; set; }
public Company company { get; set; }
}
如果有人可以帮助我,我将非常感激。
编辑: 所以我做了一些改变。原来是谢谢你们,我没有给UnityWebRequest时间来获取数据。 现在,我收到了另一个错误“ ArgumentException:JSON必须表示一个对象类型。”
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Net;
using System.IO;
public class Houses : MonoBehaviour
{
public GameObject Prefab;
public string jsonURL;
void Update()
{
if (Input.GetKeyUp(KeyCode.T))
{
onClick();
}
}
public void processJsonData(string _url)
{
RootObject[] rootObjects = JsonUtility.FromJson<RootObject[]>(_url);
Debug.Log(rootObjects[0].id);
}
IEnumerator getData()
{
Debug.Log("Procesing data, please wait.");
//WWW _www = new WWW(jsonURL);
UnityWebRequest request = UnityWebRequest.Get("https://jsonplaceholder.typicode.com/users");
yield return request.SendWebRequest();
if (request.error == null)
{
processJsonData(request.downloadHandler.text);
}
else
{
Debug.Log("Oops something went wrong.");
}
}
public void onClick()
{
//----------------------------------------------------------------------------------------
//Latitude is the Y axis, longitude is the X axis
//for (int i = 0; i < rootObjects.Length; i++)
//{
// float x = float.Parse(rootObjects[i].address.geo.lng);
// float y = float.Parse(rootObjects[i].address.geo.lat);
// Instantiate(Prefab, new Vector3(x, y, 0f), Quaternion.identity);
//}
StartCoroutine(getData());
}
}
//public class ListItems
//{
// //public RootObject[] rootObjects;
//public List<RootObject> rootObjects;
//}
[System.Serializable]
public class Geo
{
public string lat;
public string lng;
}
[System.Serializable]
public class Address
{
public string street;
public string suite;
public string city;
public string zipcode;
public Geo geo;
}
[System.Serializable]
public class Company
{
public string name;
public string catchPhrase;
public string bs;
}
[System.Serializable]
public class RootObject
{
public int id;
public string name;
public string username;
public string email;
public Address address;
public string phone;
public string website;
public Company company;
}```
答案 0 :(得分:3)
Untiy的JsonUtility是一个性能相对不错但序列化程序非常有限的程序。它仅支持序列化fields,而您要反序列化的对象完全由properties组成,它不支持。
(顺便说一句,Unity的默认序列化器不支持属性,这也是为什么它们不显示在字段中但显示在编辑器中的原因。)
由于它不知道如何设置该属性,因此不会,并且该属性仍保留其默认值。对于引用类型(string
,Address
等),默认值为NULL,这将导致尝试访问它们时引发异常。
要解决此问题,您需要做的就是更改要反序列化的类,以使其:
public class Geo
{
public string lat { get; set; }
public string lng { get; set; }
}
成为这个:
public class Geo
{
public string lat;
public string lng;
}
对所有班级都这样做,你应该很聪明。
编辑:正如Philip B.在回答中提到的那样,您也没有正确使用UnityWebRequest.Get
。
UnityWebRequest
不会立即解决,您必须从Unity Coroutine内部yield return...
来解决它,或者等待它像这样的阻塞循环来解决:
UnityWebRequest request = UnityWebRequest.Get("https://jsonplaceholder.typicode.com/users");
request.SendWebRequest();
while (!request.isDone) {}
当然,这被认为是非常糟糕的形式,因为它会冻结游戏直到下载数据。但是,under the hood Unity handles the downloads on background threads使得您在等待时不会阻止下载本身。
您还应该查询请求以查看是否出现任何错误,以便您可以根据需要进行处理,因为下载本身可能也会遇到问题。
if (request.isHttpError || request.isNetworkError)
{
//... handle errors here
}
else
{
RootObject[] rootObjects = JsonUtility.FromJson<RootObject[]>(request.downloadHandler.text);
}
但是,我会真的建议您按照Unity UnityWebRequest.Get
documentation中所述使用协程。如果您不熟悉Unity Coroutines,请read up,它是Unity开发的宝贵工具。
编辑2: Per this answer JsonUtility不支持将数组序列化为顶级对象,因此您必须先将数组包装在一个对象中,并反序列化。您还必须使json文件中的顶级对象成为保存该数组的对象。
[Serializable]
public class Routes
{
public RootObject[] roots;
}
如果您不控制文件的内容(并且这个想法又来自于我链接的那个出色的答案),则可以使用一些字符串魔术来实现。
string jsonString = $@"{{""roots"":{request.downloadHandler.text}}}";
答案 1 :(得分:0)
由于您没有发送GET请求,因此您尝试访问的是 var result = lst
.GroupBy(l => l.BirthDate)
.Select(cl => new
{
BirthDate = cl.First().BirthDate,
Count = cl.Count().ToString()
}).ToList();
DataTable dt = Utility.ConvertToDataTable(result);
chart2.DataSource = dt;
chart2.Name = "BirthDate";
chart2.Series["Series1"].XValueMember = "BirthDate";
chart2.Series["Series1"].YValueMembers = "Count";
this.chart2.Titles.Remove(this.chart1.Titles.FirstOrDefault());
this.chart2.Titles.Add("Weekly Enrollment Chart");
chart2.Series["Series1"].IsValueShownAsLabel = true;
,它为NULL(因此,“ NullReferenceException:对象引用未设置为对象的实例”)。
如果您点击此链接on how to use UnityWebRequest.Get,您将发现不仅需要request.downloader.text
来从URL中获取JSON字符串。
尝试以下方法:
UnityWebRequest.Get("Your_Url");
希望这会对您有所帮助。