Azure API 管理订阅数据解析 json 失败

Posted

技术标签:

【中文标题】Azure API 管理订阅数据解析 json 失败【英文标题】:Parse json Fails for Azure API Management subscription data 【发布时间】:2020-08-09 03:55:26 【问题描述】:

我运行 post 以获取 API 管理订阅数据,但无法解析返回的 json,也找不到需要对返回的字符串进行哪些进一步过滤。

邮递员显示 json 就好了。其他 APIM REST 请求解析 json 就好了。

有人能解释一下吗?

字符串 url = $"https://management.azure.com/subscriptions/XXX/resourceGroups/YYY/providers/Microsoft.ApiManagement/service/ZZZ/subscriptions?api-version=2019-12-01&$filter=(contains(name, 'myname'))";

        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"

【问题讨论】:

【参考方案1】:

我不知道您遇到的确切错误,但我怀疑问题在于您没有正确反序列化它。

如果您查看 JSON,您尝试解析的对象位于 value 中,这是一个 Json 数组。您目前要做的是将数组解析为数组包含的对象。

您需要做的是将第三个对象作为其他对象的“容器”

public class Container

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

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

或者您可以将 Json 解析为 JObject 并将令牌解析为 value,这样您的 JSON 就变成了 Metadata 对象的数组,然后您可以将其反序列化为对象的集合。

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

注意事项

我以IEnumerable&lt;&gt; 为例,您可以使用您想要的任何类型的集合。数组、列表等

此外,您应该使用正确的 Async/Await 模式而不是 .Result,因为 .Result 会导致阻塞。有关.Resultawait 的信息,请参阅Jon Skeet 在this question 上的回答。

【讨论】:

谢谢@li223,收藏了!但是使用 foreach (var a in myobj) Console.Write(a.name); 循环遍历您在上面创建的 myobj a.name 返回错误 a.name 错误 CS0103:当前上下文中不存在名称“a”?然后创建容器 var obj2 = JsonConvert.DeserializeObject(newjson); throws:无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型 'ARTFunctions.MyContainer',因为该类型需要 JSON 对象(例如 "name":"value")才能正确反序列化。要修复此错误,请将 JSON 更改为 JSON 对象(例如 "name":"value") 所以我将您的容器属性更改为“名称”而不是“计数”,但仍然存在相同的错误。注意:我也按照 json = await content.ReadAsStringAsync(); 的建议进行了修改,谢谢! 属性名。这是为了帮助正确序列化 JSON。如果查看 JSON,您会看到根具有 valuecount 属性。 value 是您的元数据对象的集合,countvalue 中的对象数量 我把评论搞砸了,所以我重新发布它:a 的错误可能是因为您试图在 foreach 循环范围之外调用 a。我必须查看代码才能确定。至于您的 JSON 错误,这是因为您可能试图将 value 解析为 MyContainer 而不是 IEnumerable&lt;UserAPIMSubscriptionMetaData&gt;。如果您正在解析原始响应,请解析为 MyContainer。如果您只是尝试解析 value 而不是整个 JSON,请解析为元数据对象的集合 啊,是的。抱歉,我对此不太清楚。您需要像您所做的那样遍历Container.Value

以上是关于Azure API 管理订阅数据解析 json 失败的主要内容,如果未能解决你的问题,请参考以下文章

在 Azure API 管理服务上将多个产品添加到订阅

Azure 资源管理器 API 用户的订阅范围授权

为用户创建订阅的 Azure API 管理 REST 调用(缺失)

有没有办法通过 Azure API 管理中的订阅来改变速率限制的值

在 Azure API 管理中,当不需要订阅时,如何为 API 解决产品级策略?

如何将 Azure API 管理与 Paypal 集成