Десериализовать JSON строку, встроенную в JSON напрямую - PullRequest
1 голос
/ 23 апреля 2020

Я использую .netcore 3.1 и System.Text.Json для сериализации и десериализации. Я не знал, как точно сформулировать свой вопрос. Я оглянулся, но не смог найти прямой ответ на свой вопрос.

Извините, если это дубликат.

Это пример ответа JSON.

{
    "properties": {
        "subscriptionId": "sub1",
        "usageStartTime": "2015-03-03T00:00:00+00:00",
        "usageEndTime": "2015-03-04T00:00:00+00:00",
        "instanceData": "{\"Microsoft.Resources\":{\"resourceUri\":\"resourceUri1\",\"location\":\"Alaska\",\"tags\":null,\"additionalInfo\":null}}",
        "quantity": 2.4000000000,
        "meterId": "meterID1"
    }
}

Меня интересует прямой анализ instanceData. Если вы внимательно наблюдаете, instanceData - это вложенная строка JSON.

{
    "Microsoft.Resources": {
        "resourceUri": "resourceUri1",
        "location": "Alaska",
        "tags": null,
        "additionalInfo": null
    }
}

Вопрос:

Возможно ли проанализировать instanceData, пока целое Json анализируется? Можем ли мы добавить поле Attributes в instanceData для прямого анализа? Прямо сейчас я обращаюсь к строке из проанализированного модельного класса и разбираю instanceData отдельно.

Вот что я сейчас делаю (что-то вроде этого):

JsonSerializer.Deserialize<MicrosoftResources>(parsedResponse.instanceData).

Я уже построил классы моделей для instanceData и других объектов. В настоящее время instanceData относится к типу string в моем классе root модели.

Ответы [ 2 ]

1 голос
/ 23 апреля 2020

Я заинтересован в непосредственном разборе instanceData. Если вы внимательно наблюдаете, instanceData - это внедренная JSON строка

Возможно ли проанализировать этот instanceData во время анализа всего Json?

Вы можете выполнить вышеуказанное требование путем создания и использования пользовательского конвертера , как показано ниже.

public class ResConverter : JsonConverter<InstanceData>
{
    public override InstanceData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        //you can implement it based on your actual requirement
        //...

        string jsonData = reader.GetString();

        var instanceData = System.Text.Json.JsonSerializer.Deserialize<InstanceData>(jsonData);

        return instanceData;
    }

Классы моделей

public class MyModel
{
    public Properties Properties { get; set; }
}

public class Properties
{
    public string SubscriptionId { get; set; }
    public DateTimeOffset UsageStartTime { get; set; }
    public DateTimeOffset UsageEndTime { get; set; }

    [JsonConverter(typeof(ResConverter))]
    public InstanceData InstanceData { get; set; }
    public double Quantity { get; set; }
    public string MeterId { get; set; }
}

public class InstanceData
{
    [JsonPropertyName("Microsoft.Resources")]
    public MicrosoftResources MicrosoftResources { get; set; }
}

public class MicrosoftResources
{
    public string ResourceUri { get; set; }
    public string Location { get; set; }
    public object Tags { get; set; }
    public object AdditionalInfo { get; set; }
}

Тестовый код и результат

var jsondata = "{\"Properties\":{\"SubscriptionId\":\"sub1\",\"UsageStartTime\":\"2015-03-03T00:00:00+00:00\",\"UsageEndTime\":\"2015-03-04T00:00:00+00:00\",\"InstanceData\":\"{\\u0022Microsoft.Resources\\u0022:{\\u0022ResourceUri\\u0022:\\u0022resourceUri1\\u0022,\\u0022Location\\u0022:\\u0022Alaska\\u0022,\\u0022Tags\\u0022:null,\\u0022AdditionalInfo\\u0022:null}}\",\"Quantity\":2.4,\"MeterId\":\"meterID1\"}}";

MyModel myModel = System.Text.Json.JsonSerializer.Deserialize<MyModel>(jsondata);

enter image description here

0 голосов
/ 23 апреля 2020

Если вы можете изменить instanceData на Json вместо строки, подобной этой.

{
    "properties": {
        "subscriptionId": "sub1",
        "usageStartTime": "2015-03-03T00:00:00+00:00",
        "usageEndTime": "2015-03-04T00:00:00+00:00",
        "instanceData": {"Microsoft.Resources":{"resourceUri":"resourceUri1","location":"Alaska","tags":null,"additionalInfo":null}},
        "quantity": 2.4000000000,
        "meterId": "meterID1"
    }
}

Вы можете легко десериализовать ваш Json, используя приведенный ниже пример.

Модель Классы:

public partial class Properties
{
    [JsonPropertyName("properties")]
    public PropertiesClass PropertiesProperties { get; set; }
}

public partial class PropertiesClass
{
    [JsonPropertyName("subscriptionId")]
    public string SubscriptionId { get; set; }

    [JsonPropertyName("usageStartTime")]
    public DateTimeOffset UsageStartTime { get; set; }

    [JsonPropertyName("usageEndTime")]
    public DateTimeOffset UsageEndTime { get; set; }

    [JsonPropertyName("instanceData")]
    public InstanceData InstanceData { get; set; }

    [JsonPropertyName("quantity")]
    public double Quantity { get; set; }

    [JsonPropertyName("meterId")]
    public string MeterId { get; set; }
}

public partial class InstanceData
{
    [JsonPropertyName("Microsoft.Resources")]
    public MicrosoftResources MicrosoftResources { get; set; }
}

public partial class MicrosoftResources
{
    [JsonPropertyName("resourceUri")]
    public string ResourceUri { get; set; }

    [JsonPropertyName("location")]
    public string Location { get; set; }

    [JsonPropertyName("tags")]
    public object Tags { get; set; }

    [JsonPropertyName("additionalInfo")]
    public object AdditionalInfo { get; set; }
}

Использование:

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

class Program
{
    static void Main(string[] args)
    {
        // escaped version, just for demo
        var json =
            "{\r\n    \"properties\": {\r\n        \"subscriptionId\": \"sub1\",\r\n        \"usageStartTime\": \"2015-03-03T00:00:00+00:00\",\r\n        \"usageEndTime\": \"2015-03-04T00:00:00+00:00\",\r\n        \"instanceData\": {\"Microsoft.Resources\":{\"resourceUri\":\"resourceUri1\",\"location\":\"Alaska\",\"tags\":null,\"additionalInfo\":null}},\r\n        \"quantity\": 2.4000000000,\r\n        \"meterId\": \"meterID1\"\r\n    }\r\n}";
        var props = JsonSerializer.Deserialize<Properties>(json);

    }
}

Реквизит будет иметь все данные. Надеюсь, это поможет.

...