簡體   English   中英

如何從嵌套的 JSON 數組中按鍵獲取值?

[英]How to get a value by key from inside a nested JSON Array?

使用 JSON 結果如下所示。 我正在嘗試從“ActionId”中獲取值,在這種情況下為“b0160455-e9d5-4692-850e-4958c8c45f8c”

渲染到 Razor 頁面列表視圖時,我需要在 foreach 循環中訪問此值。

到目前為止,我已經能夠訪問第一級對象:

例子:

@foreach (var item in Model.LogEvents.EventEntities)
{
      @Html.DisplayFor(modelItem => item.Level)
}

但我只是無法計算出所需的代碼來從這個 JSON 結果中的嵌套數組“屬性”中獲取值:

  {
  "lastReadEventId": "event-58cc86503c8d08d8313d010000000000",
  "scannedEventCount": 1,
  "eventEntities": [
    {
      "timestamp": "2020-08-09T18:55:05.0779216+01:00",
      "properties": [
        {
          "name": "SourceContext",
          "value": "WebApp_RAZOR.Pages.Logs.IndexModel"
        },
        {
          "name": "ActionId",
          "value": "b0160455-e9d5-4692-850e-4958c8c45f8c"
        },
        {
          "name": "ActionName",
          "value": "/Logs/Index"
        },
        {
          "name": "RequestId",
          "value": "0HM1SHK90IVGB:00000001"
        },
        {
          "name": "RequestPath",
          "value": "/Logs/Index"
        },
        {
          "name": "SpanId",
          "value": "|e7eeae4d-4d24315c2124a72d."
        },
        {
          "name": "TraceId",
          "value": "e7eeae4d-4d24315c2124a72d"
        },
        {
          "name": "ParentId",
          "value": ""
        },
        {
          "name": "MachineName",
          "value": "DESKTOP-OS52032"
        },
        {
          "name": "ProcessId",
          "value": 22676
        },
        {
          "name": "ThreadId",
          "value": 14
        }
      ],
      "messageTemplateTokens": [
        {
          "text": "superadmin@hjbuybub.onmicrosoft.com requested the Index page"
        }
      ],
      "eventType": "$DA057814",
      "level": "Information",
      "renderedMessage": "superadmin@gegerggere.onmicrosoft.com requested the Index page",
      "id": "event-5345465467567b575675",
      "links": {
        "Self": "api/events/event-55b5456yubu5u67ub7u5{?download,render,clef}",
        "Group": "api/events/resources"
      }
    }
  ]
}

從 json 結果派生的類:

    public class LogEvents
    {
        public string LastReadEventId { get; set; }
        public int ScannedEventCount { get; set; }
        public EventEntity[] EventEntities { get; set; }
    }

    public class EventEntity
    {
        public DateTime Timestamp { get; set; }
        public Property[] Properties { get; set; }
        public MessageTemplateToken[] MessageTemplateTokens { get; set; }
        public string EventType { get; set; }
        public string Level { get; set; }
        public string RenderedMessage { get; set; }
        public string Id { get; set; }
        public Links Links { get; set; }
    }

    public class Links
    {
        public string Self { get; set; }
        public string Group { get; set; }
    }

    public class Property
    {
        public string Name { get; set; }
        public object Value { get; set; }
    }

    public class MessageTemplateToken
    {
        public string Text { get; set; }
    } 

我在這里嘗試過其他問答,但每個人的要求總是不同的並且卡住了。

一種選擇是使用 Newtonsoft 的 Json.NET json 路徑實現

var actionIds = JObject.Parse(json)
    .SelectTokens("$.eventEntities[*].properties[?(@.name == 'ActionId')].value")
    .Select(p => p.ToString())
    .ToList();

或者使用您的 class 結構,它應該是:

var actionIds = Model.LogEvents
    .SelectMany(le => le.Properties)
    .Where(p => p.Name == "ActionId")
    .Select(p => p.Value) // also can add `ToString` here since Value is an object
    .ToList();

嘗試使用 CHOETL json 閱讀器(來自掘金)。 您需要從那里加載 JSON 並讀取 JSON 並使用動態“foreach 項”。 如果 item.name == "ActionId",那么對 item.value 做任何你想做的事情。

這是指南: https://github.com/Cinchoo/ChoETL

像這樣:

@foreach (var item in Model.LogEvents.EventEntities)
{
      @Html.DisplayFor(modelItem => item.Level.Properties
        .Single(x => x.Name == "ActionId").Value)
}

這意味着“在item.Properties數組中,獲取x.Name等於"ActionId"的唯一元素 x 並返回其.Value

如果您不希望它在沒有這樣的元素時崩潰,您可以查看:

@Html.DisplayFor(modelItem => 
  (
    item.Level.Properties
      .SingleOrDefault(x => x.Name == "ActionId") 
      ?? new Property(){ Value = "Not found" }
  ).Value

Single[OrDefault] 堅持只匹配規則的一個元素。 如果您不希望它在有多個名稱為 ActionId 的元素時崩潰,請使用[First/Last][OrDefault] 如果您想要一個既不是第一個也不是最后一個的 ActionId,您必須通過任何邏輯來挖掘它以找到您需要的它們(即“第二個”、“值以 'a' 開頭的那個”等)


真的,您甚至不應該在您的視圖中執行所有這些代碼。 准備 model 並將其發送到視圖的整個想法是 model 已准備好 go 具有簡單的屬性和數據,為視圖格式化和准備。 在你看來,你不應該做大量復雜的 LINQ、錯誤處理、moel 轉換等。

“僅僅因為你可以,並不意味着你應該”:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM