c# - 我有比这更好的反序列化谷歌之家 JSON 的方法吗?
问题描述
所以我正在尝试反序列化 Google 主页 JSON(使用 Dialogflow),这样我就可以轻松地使用它,即能够像这样调用它:
string myname = tlr?.queryResult?.parameters?.name ?? "Bill";
具体来说,我正在寻求一种更好的方式来布局 Json 以更好地处理子部分,目前顶层的所有内容都使得深度嵌套的 Json neigh 难以阅读。
在底部,是我想要的工作,但我不确定如何让 C# 管理它。
Json 看起来像这样:
{
"responseId": "64de67a1-7924-437f-aa29-dad7a1451b58",
"queryResult":
{
"queryText": "Daves Mud",
"parameters":
{
"name": "Dave"
},
"allRequiredParamsPresent": true,
"fulfillmentMessages":
[
{
"text":
{
"text":
[
""
]
}
}
],
"intent":
{
"name": "projects/davesmud/agent/intents/4e264eaf-30bc-4db3-8a51-bbfe4b4a3199",
"displayName": "actions.intent.PLAY_GAME"
},
"intentDetectionConfidence": 1,
"languageCode": "en"
},
"originalDetectIntentRequest": {
"payload": {}
},
"session": "projects/davesmud/agent/sessions/a6ef333e-c870-b00e-9b94-ab36d64de757"
}
我处理它的代码是(有效):
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Daves.Mud
{
public class parameters
{
[JsonProperty("name")]
public string name {get;set;}
}
public class queryResult
{
[JsonProperty("queryText")]
public string queryText {get;set;}
[JsonProperty("parameters")]
public parameters parameters {get; set;}
[JsonProperty("allRequiredParamsPresent")]
public string allRequiredParamsPresent {get;set;}
[JsonProperty("fulfillmentMessages")]
public List<fulfillmentMessages> fulfillmentMessages {get;set;}
[JsonProperty("intent")]
public intent intent {get; set;}
[JsonProperty("intentDetectionConfidence")]
public float intentDetectionConfidence {get; set;}
[JsonProperty("languageCode")]
public string languageCode {get; set;}
}
public class text
{
[JsonProperty("text")]
public List<string> textarr {get; set;}
}
public class fulfillmentMessages
{
[JsonProperty("text")]
public text text {get; set;}
}
public class intent
{
[JsonProperty("name")]
public string name {get; set;}
[JsonProperty("displayName")]
public string displayName {get; set;}
}
public class payload
{
// don't know what gets passed to this yet.
}
public class originalDetectIntentRequest
{
[JsonProperty("payload")]
public payload payload {get; set;}
}
public class TopLevelRequest
{
[JsonProperty("responseID")]
public string responseID {get;set;}
[JsonProperty("queryResult")]
public queryResult queryResult {get; set;}
[JsonProperty("originalDetectIntentRequest")]
public originalDetectIntentRequest originalDetectIntentRequest {get; set;}
[JsonProperty("session")]
public string session {get; set;}
}
public static class HttpTriggerAlexaAdventure
{
[FunctionName("HttpTriggerAlexaAdventure")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
TopLevelRequest tlr = JsonConvert.DeserializeObject<TopLevelRequest>(requestBody);
string myname = tlr?.queryResult?.parameters?.name ?? "Bill";
/* dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
*/
return(ActionResult)new OkObjectResult($"Hello, {myname}");
}
}
}
我想要的是这样的东西,注意这不会编译,因为类不能以这种方式与属性一起使用(我认为它们被调用)。
public class TopLevelRequest
{
[JsonProperty("responseID")]
public string responseID {get;set;}
[JsonProperty("queryResult")]
public class queryResult
{
[JsonProperty("queryText")]
public string queryText {get;set;}
[JsonProperty("parameters")]
public class parameters
{
[JsonProperty("name")]
public string name {get;set;}
}
[JsonProperty("allRequiredParamsPresent")]
public string allRequiredParamsPresent {get;set;}
[JsonProperty("fulfillmentMessages")]
public class fulfillmentMessages
{
[JsonProperty("text")]
public class text
{
[JsonProperty("text")]
public List<string> textarr {get; set;}
}
...
如上所述,该类是在另一个类中定义的,因此只定义了一个顶级类,并且 json 更容易遵循,因为您不需要在源代码周围跳转。
任何建议都将不胜感激,因为如果这是最好的 c# 可以为 json 处理的可读性做的事情,我会渴望我以前在 Perl 中是如何做到的...... :-)
编辑 - 我玩了更多,并找到了一种至少保持层次结构的方法,这主要是我所追求的。说它漂亮虽然是一个光头谎言,但我相信它需要改进。
public class TopLevelRequest
{
[JsonProperty("responseID")] public string responseID {get;set;}
[JsonProperty("queryResult")] public queryResult_class queryResult {get; set;} public class queryResult_class
{
[JsonProperty("queryText")] public string queryText {get;set;}
[JsonProperty("parameters")] public parameters_cl parameters {get; set;} public class parameters_cl
{
[JsonProperty("name")] public string name {get;set;}
}
[JsonProperty("allRequiredParamsPresent")] public string allRequiredParamsPresent {get;set;}
[JsonProperty("fulfillmentMessages")] public List<fulfillmentMessages_class> fulfillmentMessages {get;set;} public class fulfillmentMessages_class
{
[JsonProperty("text")] public text_class text {get; set;} public class text_class
{
[JsonProperty("text")] public List<string> textarr {get; set;}
}
}
[JsonProperty("intent")] public intent_class intent {get; set;} public class intent_class
{
[JsonProperty("name")] public string name {get; set;}
[JsonProperty("displayName")] public string displayName {get; set;}
}
[JsonProperty("intentDetectionConfidence")] public float intentDetectionConfidence {get; set;}
[JsonProperty("languageCode")] public string languageCode {get; set;}
}
[JsonProperty("originalDetectIntentRequest")] public originalDetectIntentRequest_class originalDetectIntentRequest {get; set;} public class originalDetectIntentRequest_class
{
[JsonProperty("payload")] public payload_class payload {get; set;} public class payload_class
{
// don't know what gets passed to this yet.
}
}
[JsonProperty("session")] public string session {get; set;}
}
如果有更好的方法请告诉我:-)!
编辑 2 - 我尝试按照一张海报的建议复制 json,然后使用、编辑、特殊粘贴、将 json 作为类粘贴到 Visual Studio 中。
它直接开箱即用,这就是它产生的结果,我确信我可以像上面那样重新排序它,我很惊讶我不需要任何 JsonProperties 本身就可以大大简化代码。
这是它产生的代码:
public class TopLevelRequest
{
public string responseId { get; set; }
public Queryresult queryResult { get; set; }
public Originaldetectintentrequest originalDetectIntentRequest { get; set; }
public string session { get; set; }
}
public class Queryresult
{
public string queryText { get; set; }
public Parameters parameters { get; set; }
public bool allRequiredParamsPresent { get; set; }
public Fulfillmentmessage[] fulfillmentMessages { get; set; }
public Intent intent { get; set; }
public int intentDetectionConfidence { get; set; }
public string languageCode { get; set; }
}
public class Parameters
{
public string name { get; set; }
}
public class Intent
{
public string name { get; set; }
public string displayName { get; set; }
}
public class Fulfillmentmessage
{
public Text text { get; set; }
}
public class Text
{
public string[] text { get; set; }
}
public class Originaldetectintentrequest
{
public Payload payload { get; set; }
}
public class Payload
{
}
这太棒了,因为我认为我花了 2-3 小时来制定原始代码来映射它,这几乎是即时的!:) 他推荐的网站也很有希望。
解决方案
CodeReview StackExchange更适合这种情况,因为这主要是基于意见,使代码更可用,这是一个崇高的事业。
我要补充的一件事是,在 Visual Studio 中理解大型 Json 的一种好方法是创建一个新的 .cs 文件并将 Json 放在剪贴板中:编辑 > 选择性粘贴 > 将 Json 粘贴为类。关于起点非常方便。
推荐阅读
- caching - NUXT.JS 存储/缓存 API 请求
- java - 将 12 小时时间格式转换为 24 小时格式
- c - 输出如何 1 和 4 。我无法理解c程序背后的逻辑?
- gcc - GCC 库中不存在 libstdc++.a
- javascript - How can make a list from matrix in javascript?
- php - 提交表单后如何查看表单中输入的数据
- reactjs - 获取错误无法解构属性,因为它是未定义的
- gwt - GWT 应用程序在 devmode 下工作,但在编译后不工作
- java - 使用 SSL 的 nginx 反向代理背后的 Keycloak
- css - 如何将侧栏的位置更改为右侧?