Ошибка синтаксического анализа json для данных подписки на управление API Azure

Я запускаю сообщение, чтобы получить данные подписки на Управление API, но не могу проанализировать возвращенный json и не могу найти, какая дополнительная фильтрация требуется для возвращаемой строки.

Почтальон отлично показывает json. Другие запросы APIM REST просто разбирают json.

Кто-нибудь может пролить свет?

string url = $ "https://management.azure.com/subscriptions/XXX/resourceGroups/YYY/providers/Microsoft.ApiManagement/service/ZZZ/subscriptions?api-version=2019-12-01& $ filter = (содержит (имя, '{мое имя}')) ";

        string json = null;
        using (HttpClient client = new HttpClient())
        {
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", bearerToken);
            using (HttpResponseMessage response2 = client.GetAsync(url).Result)
            {
                using (HttpContent content = response2.Content)
                {
                    json = content.ReadAsStringAsync().Result;

                    //JObject s = JObject.Parse(json);//didn't work
                    //Console.WriteLine((string)s["name"]);//didn't work
                    //var user = JsonConvert.DeserializeObject<UserAPIMSubscriptionMetaData>(json);//didn't work
                    //var user3 = JsonConvert.DeserializeObject(json);//didn't work

                    var json2 = json.Replace("\r\n", "");
                    json2 = json2.Replace(" ", "");// first replace didn't work so tried adding this one too but didn't work either
                    //var a = JObject.Parse(json2);//tried this too but didn't work
                    var user = JsonConvert.DeserializeObject<UserAPIMSubscriptionMetaData>(json2);
                }
            }
        }


internal class properties
{
    [JsonProperty("ownerId")]
    public string ownerId { get; set; }
    [JsonProperty("scope")]
    public string scope { get; set; }
    [JsonProperty("displayName")]
    public string displayName { get; set; }
    [JsonProperty("state")]
    public string state { get; set; }
    [JsonProperty("createdDate")]
    public string createdDate { get; set; }
    [JsonProperty("startDate")]
    public string startDate { get; set; }
    [JsonProperty("expirationDate")]
    public string expirationDate { get; set; }
    [JsonProperty("endDate")]
    public string endDate { get; set; }
    [JsonProperty("notificationDate")]
    public string notificationDate { get; set; }
    [JsonProperty("stateComment")]
    public string stateComment { get; set; }
    [JsonProperty("allowTracing")]
    public string allowTracing { get; set; }
}
internal class UserAPIMSubscriptionMetaData
{
    [JsonProperty("id")]
    public string id { get; set; }
    [JsonProperty("type")]
    public string thisType { get; set; }
    [JsonProperty("name")]
    public string name { get; set; }
    [JsonProperty("properties")]
    public properties properties { get; set; }
}

Значение исходного результата из ReadAsStringAsync ():

"{\r\n  \"value\": [\r\n    {\r\n      \"id\": \"/subscriptions/XXXXX/resourceGroups/ZZZZ/providers/Microsoft.ApiManagement/service/YYYYY/subscriptions/sergiosolorzanoSubscription\",\r\n      \"type\": \"Microsoft.ApiManagement/service/subscriptions\",\r\n      \"name\": \"sergiosolorzanoSubscription\",\r\n      \"properties\": {\r\n        \"ownerId\": \"/subscriptions/XXXX/resourceGroups/YYYY/providers/Microsoft.ApiManagement/service/ZZZ/users/sergiosolorzanogmailcom\",\r\n        \"scope\": \"/subscriptions/XXXX/resourceGroups/JJJJJ/providers/Microsoft.ApiManagement/service/ZZZZ/apis\",\r\n        \"displayName\": \"sergiosolorzanoSubscription\",\r\n        \"state\": \"active\",\r\n        \"createdDate\": \"2020-04-23T08:04:31.737Z\",\r\n        \"startDate\": null,\r\n        \"expirationDate\": null,\r\n        \"endDate\": null,\r\n        \"notificationDate\": null,\r\n        \"stateComment\": null,\r\n        \"allowTracing\": true\r\n      }\r\n    }\r\n  ],\r\n  \"count\": 1\r\n}"

person Sergio Solorzano    schedule 25.04.2020    source источник


Ответы (1)


Я не знаю точной ошибки, которую вы получаете, но подозреваю, что проблема в том, что вы неправильно ее десериализуете.

Если вы посмотрите на свой JSON, вы увидите, что объекты, которые вы пытаетесь проанализировать, находятся в value, который является массивом Json. То, что вы пытаетесь сделать в данный момент, - это проанализировать этот массив в объекте, который он содержит.

Что вам нужно сделать, так это сделать третий объект в качестве «контейнера» для других объектов.

public class Container
{
    [JsonProperty("value")]
    public IEnumerable<UserAPIMSubscriptionMetaData> Metadata {get; set;}

    [JsonProperty("count")]
    public int Count {get; set;}
}

или вы можете проанализировать Json на JObject и токен для значения, чтобы ваш JSON стал просто массивом вашего объекта Metadata, который затем можно десериализовать в коллекцию вашего объекта.

var jobj = JObject.Parse(json);
var newjson = jobj["value"].ToString();
var myobj = JsonConvert.DeserializeObject<IEnumerable<UserAPIMSubscriptionMetaData>>(newjson);

Примечания:

Я использовал IEnumerable<> как пример, вы можете использовать любой тип коллекции, какой захотите. Массив, список и т. Д.

Кроме того, вы должны использовать правильный шаблон Async / Await вместо .Result, поскольку .Result может вызвать блокировку. См. Ответ Джона Скита на этот вопрос для получения информации о .Result vs await.

person li223    schedule 25.04.2020
comment
спасибо @ li223, так что это сборник! но перебирая myobj, который вы создали выше, с помощью foreach (var a in myobj) Console.Write (a.name); a.name возвращает ошибку a.name error CS0103: имя 'a' не существует в текущем контексте? А затем создание контейнера var obj2 = JsonConvert.DeserializeObject ‹MyContainer› (newjson); throws: Невозможно десериализовать текущий массив JSON (например, [1,2,3]) в тип ARTFunctions.MyContainer, потому что для правильной десериализации типу требуется объект JSON (например, {name: value}). Чтобы исправить эту ошибку, замените JSON на объект JSON (например, {name: value}). - person Sergio Solorzano; 25.04.2020
comment
поэтому я изменил ваше свойство Container на name вместо Count, но осталась та же ошибка. Примечание. Я также внес изменения, как было предложено, в json = await content.ReadAsStringAsync (); , Спасибо! - person Sergio Solorzano; 25.04.2020
comment
Что касается названий собственности. Это поможет правильно сериализовать JSON. Если вы посмотрите на JSON, вы увидите, что у корня есть свойства value и count. value - это коллекция вашего объекта метаданных, а count - количество объектов в value - person li223; 25.04.2020
comment
Я испортил комментарий, поэтому репостю его: ошибка с a, вероятно, связана с тем, что вы пытаетесь вызвать a за пределами цикла foreach. Чтобы убедиться, мне нужно увидеть код. Что касается вашей ошибки JSON, это потому, что вы, вероятно, пытаетесь проанализировать value как MyContainer вместо IEnumerable<UserAPIMSubscriptionMetaData>. Выполните синтаксический анализ в MyContainer, если вы анализируете необработанный ответ. Выполните синтаксический анализ в коллекции вашего объекта метаданных, если вы просто пытаетесь проанализировать value вместо всего JSON - person li223; 25.04.2020
comment
Да, похоже, что a выходит за рамки, но я не понимаю, почему, потому что мы десериализуем коллекцию (myobj count = 1), поэтому foreach будет перебирать коллекцию ?: используя ваши 3 строки кода выше: var myobj = JsonConvert. DeserializeObject ‹IEnumerable ‹UserAPIMSubscriptionMetaData›› (newjson); foreach (var a in myobj) {Console.Write (a.name);} - person Sergio Solorzano; 25.04.2020
comment
Попался. var conta = JsonConvert.DeserializeObject ‹MyContainer› (json); Затем перебрал conta.value, поэтому foreach (элемент var в conta.value) Console.Write (z.name); и все свойства показывают :) большое спасибо - person Sergio Solorzano; 25.04.2020
comment
О да. Извините, я не совсем понял это. Вам нужно перебрать Container.Value, как вы это сделали. - person li223; 25.04.2020