如何在 botframework 中的 LUIS Json 字符串的新 "builtin.datetimeV2.timerange"(开始,结束)时间中提取值

How to extract values in new "builtin.datetimeV2.timerange" (start , end) time of LUIS Json string in botframework

我在 c# 中使用 botframework(Bot builder v3。8.x)来构建我的机器人,我想访问 LUIS 新 datetimeV2 实体中的值、开始和结束时间键的值。

在下面的JSON中我想提取"value": "2017-07-04", "start" : "16:00:00" & "end": "18:00:00"

{
  "entity": "july 4th",
  "type": "builtin.datetimeV2.date",
  "startIndex": 58,
  "endIndex": 65,
  "resolution": {
    "values": [
      {
        "timex": "XXXX-07-04",
        "type": "date",
        "value": "2016-07-04"
      },
      {
        "timex": "XXXX-07-04",
        "type": "date",
        "value": "2017-07-04"
      }
    ]
  }
},
{
  "entity": "from 4 pm to 6 pm",
  "type": "builtin.datetimeV2.timerange",
  "startIndex": 67,
  "endIndex": 84,
  "resolution": {
    "values": [
      {
        "timex": "(T16,T18,PT2H)",
        "type": "timerange",
        "start": "16:00:00",
        "end": "18:00:00"
      }
    ]
  }
}

我正在尝试执行以下操作,但它给出了 Null Reference Exception

        private const string DateEntityType = "builtin.datetimeV2.date";
        private const string TimeRangeEntityType = "builtin.datetimeV2.timerange";
        var entities = new List<EntityRecommendation>(result.Entities);
        foreach (var entity in result.Entities)
        {

            switch (entity.Type)
            {
                case DateEntityType:
                    var date = entity.Resolution.Values.GetType().GetRuntimeProperty("value").ToString() ?? null;
                    break;
                case TimeRangeEntityType:
                    var startTime = entity.Resolution.Values.GetType().GetRuntimeProperty("start").ToString() ?? null;
                    var endTime = entity.Resolution.Values.GetType().GetRuntimeProperty("end").ToString() ?? null;
                    break;

                default:
                    break;
            }
        }

获取这些值的最简单方法是什么?

这肯定不是最优雅的方式,但我在 Newtonsoft 的一点帮助下设法从结构中获取数据:

if (entity.Type == "builtin.datetimeV2.daterange")
{
    foreach (var vals in entity.Resolution.Values)
    {
        if (((Newtonsoft.Json.Linq.JArray)vals).First.SelectToken("type").ToString() == "daterange")
        {
            start = (DateTime)((Newtonsoft.Json.Linq.JArray)vals).First.SelectToken("start");
            end = (DateTime)((Newtonsoft.Json.Linq.JArray)vals).First.SelectToken("end");
        }
    }
}

希望你明白了。

与 Patrik B 相同,但使用 Newtonsoft 的 JObject。

        case TimeRangeEntityType:
                object jsonstring;
                entity.Resolution.TryGetValue("values", out jsonstring);

                //Remove the first and last characters so that we get a proper json string
                var WellformedJson = jsonstring.ToString().Substring(1, jsonstring.ToString().Length - 2);
                JObject jobj = JObject.Parse(WellformedJson);
                var startTime = (DateTime)jobj["start"];
                var endTime = (DateTime)jobj["end"];

我使用 json2csharp 为 LuisResult 创建模型。

    public class TopScoringIntent
{
    public string intent { get; set; }
    public double score { get; set; }
}

public class Intent
{
    public string intent { get; set; }
    public double score { get; set; }
}

public class Value
{
    public string timex { get; set; }
    public string type { get; set; }
    public string start { get; set; }
    public string end { get; set; }
}

public class Resolution
{
    public List<Value> values { get; set; }
}

public class Entity
{
    public string entity { get; set; }
    public string type { get; set; }
    public int startIndex { get; set; }
    public int endIndex { get; set; }
    public Resolution resolution { get; set; }
}

public class LuisResultModel
{
    public string query { get; set; }
    public TopScoringIntent topScoringIntent { get; set; }
    public List<Intent> intents { get; set; }
    public List<Entity> entities { get; set; }
}

然后我将 LuisResult 序列化为 json,然后再将其反序列化为我的新模型:

var t = JsonConvert.SerializeObject(luisResult);
_luisResult = JsonConvert.DeserializeObject<LuisResultModel>(t);

其中 _luisResult 是 LuisResultModel 类型。这是一个强类型对象,我现在可以这样做了。

var startDate = _luisResult.Entity.First().resolution.values.First().start;
var endDate = _luisResult.Entity.First().resolution.values.First().end;

做一些通用的事情?我不喜欢那么多如果。

public static V GenericLuisEntityResolution<V>(EntityRecommendation entity)
        {
            dynamic result = null;

            if (entity.Resolution == null)
            {
                result = entity.Entity;
            } else
            {
                dynamic value = entity.Resolution.FirstOrDefault().Value;
                result = value[0];
            }

            return result;
        }

 Dictionary<string,dynamic> date = GenericLuisEntityResolution<dynamic>(yourdata...);
  date ["start"].....