我有比这更好的反序列化Google Homes JSON的方法吗?

时间:2019-03-13 18:31:11

标签: c# json serialization dialogflow

因此,我正在尝试反序列化Google homes JSON(使用Dialogflow),以便我可以轻松地使用它,即可以这样调用它:

        string myname = tlr?.queryResult?.parameters?.name ?? "Bill";

特别是我正在寻找一种更好的方式来布局Json以更好地处理子部分,目前所有内容都位于顶层,这使嵌套Json的邻居变得难以理解。

最下面是我想要的工作,但是我不确定如何让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个小时的时间才能完成原始代码的映射,而且这几乎是瞬间! :)他推荐的网站也很有希望。

1 个答案:

答案 0 :(得分:1)

CodeReview StackExchange更适合此操作,因为这主要是基于观点的观点,以使代码更易用,这是一个高贵的原因。

我要添加的一件事是,在Visual Studio中理解大型Json的一种好方法是创建一个新的.cs文件并将Json放在剪贴板中:编辑>选择性粘贴>将Json粘贴为类。在出发点方面非常方便。