Unity JSON 序列化程序不允许调用 JSON 字段 n JSON 个对象
Unity JSON Serializer not allowing for calling JSON Fields n JSON Objects
我无法从抓取的网站调用嵌套的 JSON 对象。抓取过程完美无缺,但 JSON 序列化部分是唯一的问题。我的代码如下所示:
private void GetHtmlAsync()
{
var url = "https://opentdb.com/api.php?amount=10";
var httpClient = new HttpClient();
var html = httpClient.GetStringAsync(url);
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(MyDetail));
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(html.Result));
stream.Position = 0;
MyDetail dataContractDetail = (MyDetail) jsonSerializer.ReadObject(stream);
text.text = "" + dataContractDetail.results[1];
//text.text = string.Concat("Test: ", dataContractDetail.question, " " + dataContractDetail.correct_answer);
}
public class MyDetail
{
[DataMember]
public Dictionary<string, questions> results
{
get;
set;
}
public class questions
{
public string question { get; set; }
public string correct_answer { get; set; }
}
[DataMember]
public string response_code
{
get;
set;
}
}
此代码无效,因为我尝试通过 "results[1]" 调用结果中的第一个对象,这 returns 在我附加 [=] 之后出现错误20=] 通过做 "results[1].question"。这种语法似乎很合理,所以我不明白为什么它不起作用。我的 JSON 文件如下所示:
{
"response_code": 0,
"results": [
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "medium",
"question": "What is the name of the virus in "Metal Gear Solid 1"?",
"correct_answer": "FOXDIE",
"incorrect_answers": [
"FOXENGINE",
"FOXALIVE",
"FOXKILL"
]
},
{
"category": "Geography",
"type": "multiple",
"difficulty": "easy",
"question": "What is the official language of Costa Rica?",
"correct_answer": "Spanish",
"incorrect_answers": [
"English",
"Portuguese",
"Creole"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "medium",
"question": "In Fallout 4, which type of power armor is first encountered in the early mission "When Freedom Calls" in a crashed Vertibird?",
"correct_answer": "T-45",
"incorrect_answers": [
"T-51",
"T-60",
"X-01"
]
},
{
"category": "Politics",
"type": "boolean",
"difficulty": "medium",
"question": "George W. Bush lost the popular vote in the 2004 United States presidential election.",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "medium",
"question": "In "Halo 2", what is the name of the monitor of Installation 05?",
"correct_answer": "2401 Penitent Tangent",
"incorrect_answers": [
"343 Guilty Spark",
"031 Exuberant Witness",
"252 Biodis Expolsion"
]
},
{
"category": "Entertainment: Books",
"type": "multiple",
"difficulty": "medium",
"question": "The book "Fahrenheit 451" was written by whom?",
"correct_answer": "Ray Bradbury",
"incorrect_answers": [
"R. L. Stine",
"Wolfgang Amadeus Mozart",
"Stephen King"
]
},
{
"category": "Entertainment: Cartoon & Animations",
"type": "multiple",
"difficulty": "hard",
"question": "In "Rick and Morty", from which dimension do Rick and Morty originate from?",
"correct_answer": "C-137",
"incorrect_answers": [
"J1977",
"C-136",
"C500-a"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "hard",
"question": "In which game did the character "Mario" make his first appearance?",
"correct_answer": "Donkey Kong",
"incorrect_answers": [
"Super Mario Bros.",
"Super Mario Land",
"Mario Bros."
]
},
{
"category": "Entertainment: Film",
"type": "multiple",
"difficulty": "hard",
"question": "What was Humphrey Bogart's middle name?",
"correct_answer": "DeForest",
"incorrect_answers": [
"DeWinter",
"Steven",
"Bryce"
]
},
{
"category": "Entertainment: Cartoon & Animations",
"type": "boolean",
"difficulty": "medium",
"question": "In "Avatar: The Last Airbender" and "The Legend of Korra", Lavabending is a specialized bending technique of Firebending.",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
}
]
}
您的代码中存在很多问题。我不知道您正在使用的所有库,但我会这样做。
首先你开始 GetStringAsync
但你立即继续而不等待结果。我不知道您正在使用的所有库,当然也许它应该是这样的?
不过我宁愿使用Unity的UnityWebRequest.Get
private void GetHtmlAsync()
{
StartCoroutine(DownloadJson());
}
private IEnumerator DownloadJson()
{
var url = "https://opentdb.com/api.php?amount=10";
using(var uwr = UnityWebRequest.Get(url))
{
// send the request and wait for result
yield return uwr.SendWebRequest();
// Check for success!
if(uwr.isNetworkError || uwr.isHttpError || !string.IsNullOrWhiteSpace(uwr.error))
{
Debug.LogError($"Download failed with {uwr.responseCode} reason: {uwr.error}", this);
yield break;
}
var json = uwr.DownloadHandler.text;
// ... se below
}
}
同样,我不知道您的 JSON 库,但您的 class 似乎与 JSON 数据结构不匹配(通过简单地将其插入 json2csharp)
[Serializable]
public class Result
{
public string category;
public string type;
public string difficulty;
public string question;
public string correct_answer;
public List<string> incorrect_answers;
}
[Serializable]
public class MyDetail
{
public int response_code;
public List<Result> results;
}
对于 Unity,我会使用 [Serializable]
并删除所有 {get;set}
以便不使用属性而是使用字段。
那么你可以简单地使用 Unity 的 JsonUtility
...
MyDetail dataContractDetail = JsonUtility.FromJson<MyDetail>(json);
然后如评论中所述,注意 c# 中的数组索引基于 0
,因此 first 元素将是
var firstResult = dataContractDetail.results[0];
现在的问题是您希望在文本中看到什么? firstResult
不是 string
而是具有不同成员的 class!你可以例如想显示像
这样的问题
text.text = firstResult.question;
我无法从抓取的网站调用嵌套的 JSON 对象。抓取过程完美无缺,但 JSON 序列化部分是唯一的问题。我的代码如下所示:
private void GetHtmlAsync()
{
var url = "https://opentdb.com/api.php?amount=10";
var httpClient = new HttpClient();
var html = httpClient.GetStringAsync(url);
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(MyDetail));
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(html.Result));
stream.Position = 0;
MyDetail dataContractDetail = (MyDetail) jsonSerializer.ReadObject(stream);
text.text = "" + dataContractDetail.results[1];
//text.text = string.Concat("Test: ", dataContractDetail.question, " " + dataContractDetail.correct_answer);
}
public class MyDetail
{
[DataMember]
public Dictionary<string, questions> results
{
get;
set;
}
public class questions
{
public string question { get; set; }
public string correct_answer { get; set; }
}
[DataMember]
public string response_code
{
get;
set;
}
}
此代码无效,因为我尝试通过 "results[1]" 调用结果中的第一个对象,这 returns 在我附加 [=] 之后出现错误20=] 通过做 "results[1].question"。这种语法似乎很合理,所以我不明白为什么它不起作用。我的 JSON 文件如下所示:
{
"response_code": 0,
"results": [
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "medium",
"question": "What is the name of the virus in "Metal Gear Solid 1"?",
"correct_answer": "FOXDIE",
"incorrect_answers": [
"FOXENGINE",
"FOXALIVE",
"FOXKILL"
]
},
{
"category": "Geography",
"type": "multiple",
"difficulty": "easy",
"question": "What is the official language of Costa Rica?",
"correct_answer": "Spanish",
"incorrect_answers": [
"English",
"Portuguese",
"Creole"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "medium",
"question": "In Fallout 4, which type of power armor is first encountered in the early mission "When Freedom Calls" in a crashed Vertibird?",
"correct_answer": "T-45",
"incorrect_answers": [
"T-51",
"T-60",
"X-01"
]
},
{
"category": "Politics",
"type": "boolean",
"difficulty": "medium",
"question": "George W. Bush lost the popular vote in the 2004 United States presidential election.",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "medium",
"question": "In "Halo 2", what is the name of the monitor of Installation 05?",
"correct_answer": "2401 Penitent Tangent",
"incorrect_answers": [
"343 Guilty Spark",
"031 Exuberant Witness",
"252 Biodis Expolsion"
]
},
{
"category": "Entertainment: Books",
"type": "multiple",
"difficulty": "medium",
"question": "The book "Fahrenheit 451" was written by whom?",
"correct_answer": "Ray Bradbury",
"incorrect_answers": [
"R. L. Stine",
"Wolfgang Amadeus Mozart",
"Stephen King"
]
},
{
"category": "Entertainment: Cartoon & Animations",
"type": "multiple",
"difficulty": "hard",
"question": "In "Rick and Morty", from which dimension do Rick and Morty originate from?",
"correct_answer": "C-137",
"incorrect_answers": [
"J1977",
"C-136",
"C500-a"
]
},
{
"category": "Entertainment: Video Games",
"type": "multiple",
"difficulty": "hard",
"question": "In which game did the character "Mario" make his first appearance?",
"correct_answer": "Donkey Kong",
"incorrect_answers": [
"Super Mario Bros.",
"Super Mario Land",
"Mario Bros."
]
},
{
"category": "Entertainment: Film",
"type": "multiple",
"difficulty": "hard",
"question": "What was Humphrey Bogart's middle name?",
"correct_answer": "DeForest",
"incorrect_answers": [
"DeWinter",
"Steven",
"Bryce"
]
},
{
"category": "Entertainment: Cartoon & Animations",
"type": "boolean",
"difficulty": "medium",
"question": "In "Avatar: The Last Airbender" and "The Legend of Korra", Lavabending is a specialized bending technique of Firebending.",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
}
]
}
您的代码中存在很多问题。我不知道您正在使用的所有库,但我会这样做。
首先你开始 GetStringAsync
但你立即继续而不等待结果。我不知道您正在使用的所有库,当然也许它应该是这样的?
不过我宁愿使用Unity的UnityWebRequest.Get
private void GetHtmlAsync()
{
StartCoroutine(DownloadJson());
}
private IEnumerator DownloadJson()
{
var url = "https://opentdb.com/api.php?amount=10";
using(var uwr = UnityWebRequest.Get(url))
{
// send the request and wait for result
yield return uwr.SendWebRequest();
// Check for success!
if(uwr.isNetworkError || uwr.isHttpError || !string.IsNullOrWhiteSpace(uwr.error))
{
Debug.LogError($"Download failed with {uwr.responseCode} reason: {uwr.error}", this);
yield break;
}
var json = uwr.DownloadHandler.text;
// ... se below
}
}
同样,我不知道您的 JSON 库,但您的 class 似乎与 JSON 数据结构不匹配(通过简单地将其插入 json2csharp)
[Serializable]
public class Result
{
public string category;
public string type;
public string difficulty;
public string question;
public string correct_answer;
public List<string> incorrect_answers;
}
[Serializable]
public class MyDetail
{
public int response_code;
public List<Result> results;
}
对于 Unity,我会使用 [Serializable]
并删除所有 {get;set}
以便不使用属性而是使用字段。
那么你可以简单地使用 Unity 的 JsonUtility
...
MyDetail dataContractDetail = JsonUtility.FromJson<MyDetail>(json);
然后如评论中所述,注意 c# 中的数组索引基于 0
,因此 first 元素将是
var firstResult = dataContractDetail.results[0];
现在的问题是您希望在文本中看到什么? firstResult
不是 string
而是具有不同成员的 class!你可以例如想显示像
text.text = firstResult.question;