У меня есть лучший способ десериализации Google Home JSON, чем этот? - PullRequest
1 голос
/ 13 марта 2019

Итак, я пытаюсь десериализовать дома Google 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 и вставить его в visual studio, используя, редактировать, вставлять специальные, вставлять json как классы.

Он работал прямо из коробки, это то, что он производит, я уверен, что я мог бы изменить порядок, как я делал выше, я был удивлен, что мне не нужен ни один из 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 Ответ

1 голос
/ 13 марта 2019

CodeReview StackExchange как нельзя лучше подходит для этого, поскольку он в первую очередь основан на мнениях относительно того, как сделать код более удобным для использования, что является благородной причиной.

Одна вещь, которую я 'Добавлю, что отличный способ разобраться с большим Json в Visual Studio - создать новый файл .cs и добавить Json в буфер обмена: «Правка»> «Специальная вставка»> «Вставить Json в классы».Довольно удобно с точки отсчета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...