Считать JSON вывод из AppInsights в C# - PullRequest
4 голосов
/ 16 января 2020

Я хочу прочитать выходные данные API AppInsights в C# консольном приложении.

WebClient wc = new WebClient();
wc.BaseAddress = "https://api.applicationinsights.io/v1/apps/AppInsighID/query?query=requests|where timestamp>= ago(1h)|limit 100";
wc.Headers.Add("Host", "api.applicationinsights.io");
wc.Headers.Add("x-api-key", "key");

string json = wc.DownloadString("");

JObject jsonObject = JObject.Parse(json);

//With this, i got values for Rows

var rowsObject = jsonObject["tables"][0]["rows"];

Теперь значения находятся в массиве, в rowObject, так как это прочитать?

Я бы тоже хотелось бы узнать лучшие практики, которым мы должны следовать при чтении json string

Я вижу такие данные

{
"tables": [
    {
        "name": "PrimaryResult",
        "columns": [
            {
                "name": "timestamp",
                "type": "datetime"
            },
            {
                "name": "id",
                "type": "string"
            },
            {
                "name": "source",
                "type": "string"
            },
            {
                "name": "name",
                "type": "string"
            },
            {
                "name": "url",
                "type": "string"
            },
            {
                "name": "success",
                "type": "string"
            },
            {
                "name": "resultCode",
                "type": "string"
            },
            {
                "name": "duration",
                "type": "real"
            },
            {
                "name": "performanceBucket",
                "type": "string"
            },
            {
                "name": "itemType",
                "type": "string"
            },
            {
                "name": "customDimensions",
                "type": "dynamic"
            },
            {
                "name": "customMeasurements",
                "type": "dynamic"
            },
            {
                "name": "operation_Name",
                "type": "string"
            },
            {
                "name": "operation_Id",
                "type": "string"
            },
            {
                "name": "operation_ParentId",
                "type": "string"
            },
            {
                "name": "operation_SyntheticSource",
                "type": "string"
            },
            {
                "name": "session_Id",
                "type": "string"
            },
            {
                "name": "user_Id",
                "type": "string"
            },
            {
                "name": "user_AuthenticatedId",
                "type": "string"
            },
            {
                "name": "user_AccountId",
                "type": "string"
            },
            {
                "name": "application_Version",
                "type": "string"
            },
            {
                "name": "client_Type",
                "type": "string"
            },
            {
                "name": "client_Model",
                "type": "string"
            },
            {
                "name": "client_OS",
                "type": "string"
            },
            {
                "name": "client_IP",
                "type": "string"
            },
            {
                "name": "client_City",
                "type": "string"
            },
            {
                "name": "client_StateOrProvince",
                "type": "string"
            },
            {
                "name": "client_CountryOrRegion",
                "type": "string"
            },
            {
                "name": "client_Browser",
                "type": "string"
            },
            {
                "name": "cloud_RoleName",
                "type": "string"
            },
            {
                "name": "cloud_RoleInstance",
                "type": "string"
            },
            {
                "name": "appId",
                "type": "string"
            },
            {
                "name": "appName",
                "type": "string"
            },
            {
                "name": "iKey",
                "type": "string"
            },
            {
                "name": "sdkVersion",
                "type": "string"
            },
            {
                "name": "itemId",
                "type": "string"
            },
            {
                "name": "itemCount",
                "type": "int"
            }
        ],
        "rows": [
            [
                "2020-01-16T07:07:35.8423912Z",
                "ID",
                "",
                "POST ",
                "https://",
                "True",
                "200",
                57.679,
                "<250ms",
                "request",
                "{\"Product Name\":\"Name\",\"Subscription Name\":\"Name\",\"Operation Name\":\"AdvancedSearch\",\"ApimanagementRegion\":\"Region\",\"ApimanagementServiceName\":\"Name\",\"Apim Request Id\":\"ID\",\"Request-Body\":\"{\\\"P1\\\":25,\\\"P2\\\":1,\\\"P3\\\":\\\"All \\\",\\\"P4\\\":\\\"Earliest\\\",\\\"P5\\\":\\\"Extended\\\",\\\"P6\\\":\\\"All \\\",\\\"P6\\\":\\\"Latest\\\",\\\"queryList\\\":[{\\\"P7\\\":\\\"physics\\\",\\\"P8\\\":\\\"A1\\\",\\\"operator\\\":\\\"\\\"}]}\",\"Cache\":\"None\",\"P9\":\"195.43.22.145\",\"API Name\":\"Name\",\"HTTP Method\":\"POST\"}",
                "{\"Response Size\":776,\"Request Size\":1092,\"Client Time (in ms)\":0}",
                "POST ",
                "ID",
                "ID",
                "",
                "",
                "",
                "1",
                "",
                "",
                "PC",
                "",
                "",
                "0.0.0.0",
                "Milan",
                "Milan",
                "Italy",
                "",
                "Value1",
                "Value2",
                "ID1",
                "AppInsight Name",
                "Name",
                "apim:0.12.885.0",
                "ID",
                1
            ]
        ]
    }
]
}

1 Ответ

3 голосов
/ 16 января 2020

Вы можете десериализовать Json и получить информацию о строках. Например,

var result = JsonConvert.DeserializeObject<RootObject>(str);
var rowData = result.tables.SelectMany(x=>x.rows.SelectMany(c=>c));

Если вы не хотите выравнивать результаты, вы можете использовать

var rowData = result.tables.SelectMany(x=>x.rows.Select(c=>c));

, где RootObject определен как

public class Column
{
    public string name { get; set; }
    public string type { get; set; }
}

public class Table
{
    public string name { get; set; }
    public List<Column> columns { get; set; }
    public List<List<string>> rows { get; set; }
}

public class RootObject
{
    public List<Table> tables { get; set; }
}

Если вы намереваясь исключить пустые значения, вы могли бы отфильтровать их, используя Linq

var rowData = result.tables.SelectMany(x=>x.rows.SelectMany(c=>c))
                           .Where(x=>!string.IsNullOrEmpty(x));

или для не сплющенных результатов

var rowData = result.tables.SelectMany(x=>x.rows.Select(c=>c))
                           .Where(x=>!string.IsNullOrEmpty(x.ToString()));

обновление

Основываясь на комментариях, чтобы получить информацию и проанализировать ее в Dto на основе позиции значений в массиве, вы можете сделать следующее. Атрибут также может быть использован для обработки встроенных Json свойств, как указано в комментарии.

Вы можете начать с определения атрибута следующим образом.

public class DtoDefinitionAttribute:Attribute
{

    public DtoDefinitionAttribute(int order)=>Order = order;
    public DtoDefinitionAttribute(int order,bool isJson,Type jsonDataType)
    {
        Order = order;
        JsonDataType = jsonDataType;
        IsJson = isJson;
    }
    public bool IsJson{get;} = false;
    public int Order{get;}
    public Type JsonDataType {get;}
}

И тогда вы может украсить ваши свойства Dto с индексом соответствующего значения в массиве. Кроме того, в случае Json строки, ожидаемой как Json, вы можете использовать атрибут, чтобы указать его, как показано в свойстве ClientTime Например,

public class Dto
{
    [DtoDefinition(0)]
    public DateTime CurrentDate{get;set;}
    [DtoDefinition(1)]
    public string ID{get;set;}
    [DtoDefinition(2)]
    public string Url{get;set;}
    [DtoDefinition(11,true,typeof(Response))]
    public Response Json1{get;set;}
}

public class Response
{
    [JsonProperty("Response Size")]
    public string ResponseSize{get;set;}

    [JsonProperty("Request Size")]
    public string RequestSize{get;set;}

    [JsonProperty("Client Time (in ms)")]
    public int ClientTime{get;set;}
}

Теперь вы можете используйте результат rowData, полученный с использованием

var listDto = new List<Dto>();
foreach(var row in rowData)
{
    listDto.Add(AssignValues(row));
}

, где AssignValues ​​определены как

public Dto AssignValues(List<string> row)
{
    var dto = new Dto();
    var properties = typeof(Dto).GetProperties().Where(x=>x.GetCustomAttributes<DtoDefinitionAttribute>().Any());
    foreach(var property in properties)
    {
        var attribute = property.GetCustomAttribute<DtoDefinitionAttribute>();
        if(attribute.IsJson)
        {
            var jsonData = row[attribute.Order].ToString();
            var deserializedData = JsonConvert.DeserializeObject(jsonData,attribute.JsonDataType);
            property.SetValue(dto,deserializedData);
        }
        else
        {
            property.SetValue(dto,Convert.ChangeType(row[attribute.Order],property.PropertyType));
        }
    }
    return dto;
}

Метод AssignValues использует отражение для чтения атрибутов и создания экземпляра Dto на основе Это. В случае, если он находит атрибут, определяющий его как Json, он десериализует значение json и использует результат.

Демонстрационный код

...