Microsoft Graph Api GET 请求在调用应用程序时无法反序列化 JSON 对象

问题描述 投票:0回答:1

我正在发出 GET 请求调用,以获取所有应用程序及其 ID 和密码到期日期。我一直在使用 Microsoft 提供的 Graph Explore,并得到了很多帮助。我的代码获取了 http 请求,然后尝试反序列化它,并出现下面给定的错误。我在 SOF 上花了很长时间查看类似的帖子,但似乎没有任何效果。我觉得我可能在这里遗漏了一些简单的东西或者以错误的方式处理它。

我还停留在旧版本的 Graph Nugget pkg v4.41.0 上,而 Core 为 v2.0.13。我去更新它们,应用程序中有很多重大更改,我还没有时间重写所有内容。

我收到以下错误:

"Message": "An error has occurred.", 
"ExceptionMessage": "Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1[Microsoft.Graph.Application]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.\r\nPath '['@odata.context']', line 1, position 18.",
"ExceptionType": "Newtonsoft.Json.JsonSerializationException",
"StackTrace": "   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)\r\n   at Newtonsoft.Json.Serialization...
        public async Task<List<Application>> GetAppExpList()
        {
           List<Application> apps = null;                       

           // query string for url call
           var url = this.GetGraphUrl($"{Consts.GraphUrl}?$select=id,passwordCredentials&$format=json");
           
           // tried to do this with the built in Graph methods
           List<QueryOption> options = new List<QueryOption>
           {
            new QueryOption("$select", "id,DisplayName,passwordCredentials"), 
            new QueryOption("$format", "json")
           };

           // Here I wanted to see what was brought back. No PasswordCreds for some reason 
           var test = await _graphClient.Applications.Request(options).GetAsync();


          // GET request to the Applications Graph Api
          var response = await this.HttpHandler.SendGraphGetRequest(url);            
        
          // Returns JSON data 
          if (response.IsSuccessStatusCode)
          {
            // Shows the correct data in JSON Format
            var rawData = await response.Content.ReadAsStringAsync();

            // Throws error above.    
            apps = JsonConvert.DeserializeObject<List<ApplicationB2C>>(rawData);
                            
          }

         return apps; 
    }

这是返回的 JSON

var rawData = await response.Content.ReadAsStringAsync();

{"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#applications(id,passwordCredentials)"
 ,"value":[
 {
    "id":"00000000-0000-0000-0000-000000000000",
    "displayName":"App 1 name Here",
    "passwordCredentials":[]
 },
 {
    "id":"00000000-0000-0000-0000-000000000001",
    "displayName":" App 2 name here",
    "passwordCredentials":[]
 },
 {
    "id":"00000000-0000-0000-0000-000000000002",
    "displayName":"App 3 name here",
    "passwordCredentials":[
       {
        "customKeyIdentifier":null,
        "displayName":"secret",
        "endDateTime":"2025-01-30T14:46:40.985Z",
        "hint":"oHI",
        "keyId":"00000000-0000-0000-0000-0000000000",
        "secretText":null,
        "startDateTime":"2023-01-31T14:46:40.985Z"
        }
     ]
  }
]

}

c# asp.net-mvc azure microsoft-graph-api azure-ad-graph-api
1个回答
0
投票

反序列化的类需要如下所示。你正在努力

apps = JsonConvert.DeserializeObject<List<ApplicationB2C>>(rawData);

如果 json 是一个带有嵌套列表的列表,那么类将需要如下所示。

ApplicationB2C
需要看起来像这样。

public class ApplicationB2C
{
    [JsonProperty("@odata.context")]
    public string data_context { get; set; }
    [JsonProperty("values")]
    public List<ValueClass> values { get; set; }
}

那么

ValueClass
就会像

public class ValueClass
{
    public Guid id { get; set; }
    public string displayName { get; set; }
    public List<PasswordCredential> PasswordCredentials { get; set; }
}

还有

public class PasswordCredential
{
    public object customerKeyIdentifier { get; set; }
    public string displayName { get; set; }
    //Add rest of properties here 
}
© www.soinside.com 2019 - 2024. All rights reserved.