Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event's class properties of Enum type failing to deserialize using Microsoft.Graph API version 5.1* #2151

Closed
astalmok opened this issue Oct 5, 2023 · 3 comments

Comments

@astalmok
Copy link

astalmok commented Oct 5, 2023

I have a working version of application which uses Microsoft.Graph API version 4.37. Now upgrading it to use version 5.1*.
The main updated/refactored code parts are working using dedicated request builders like:

var multipleEvents = (await graphClient.Me.Calendar.CalendarView.GetAsync()).Value;
var singleEvent = await graphClient.Me.Calendar.Events["Id of event"].GetAsync();

But there is a situation when I need to select different events by their IDs using Batch request. HttpRequests of type Get (by URL of event) are added to batch and multiple response contents streams in version 4.* were parsed using:

var eventX = graphClient.HttpProvider.Serializer.DeserializeObject(jsonFromResponceContent);

In version 5.1* I'm receiving such json (shortened here):
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('fb5b52e2-ce57-4273-875c-570a71c1c0d9')/events/$entity",
"@odata.etag": "W/"mv/EZgBe4U+n/DGkFJWGXQAJc2FSXg=="",
"id": "id value here",
"createdDateTime": "2014-01-06T09:04:30.4737618Z",
"lastModifiedDateTime": "2023-05-24T10:37:13.3823665Z",
"originalStartTimeZone": "UTC",
"......................................................................................
"hasAttachments": false,
"subject": "Dad's Birthday",
"importance": "normal",
"sensitivity": "normal",
........................................................
"body": {
"contentType": "html",
"content": "......"
},
"start": {
"dateTime": "1991-05-24T00:00:00.0000000",
"timeZone": "UTC"
},
"end": {
"dateTime": "1991-05-25T00:00:00.0000000",
"timeZone": "UTC"
},
.................................................
"recurrence": {
"pattern": {
"type": "absoluteYearly",
"interval": 1,
"month": 5,
"dayOfMonth": 24,
"firstDayOfWeek": "sunday",
"index": "first"
},
"range": {
"type": "noEnd",
"startDate": "1991-05-24",
"endDate": "0001-01-01",
"recurrenceTimeZone": "FLE Standard Time",
"numberOfOccurrences": 0
}
},
..........................................................
}

In version 5.* native HttpProvider nor any ISerializer no more exist or could not find where to instantiate them from. So decided to use

var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
var event = System.Text.Json.JsonSerializer.Deserialize(jsonFromResponceContent, options);

But deserializer fails throwing "The JSON value could not be converted to System.Nullable`1[Microsoft.Graph.Models.Importance]. Path: $.importance ....".

Deserializer does not fail only when all properties of type Enum or classes having enum subproperties are excluded using Select option, f.e. when URL of request is like
"https://graph.microsoft.com/v1.0/me/events/idOfEventHere?$select=id,iCalUId,subject,isAllDay,start,end,createdDateTime".
If I add "importance", "location" or "body" property to be fetched - deserialization fails on a first Enum type property.

Why it fails. What Serializer should I use?

@andrueastman
Copy link
Member

Thanks for raising this @astalmok

As you are using batch requests, is there a specific reason why you are not using the method overloads that deseialize the response for you?

var user = await batchResponseCollection.GetResponseByIdAsync<User>(userRequestId);

https://learn.microsoft.com/en-us/graph/sdks/batch-requests?tabs=csharp#simple-batching-example

@astalmok
Copy link
Author

Yes, I'm using batch requests, sometimes to select several specific events in one batch. And now ENUM issue is solved by adding JsonStringEnumConverter. Here is example code that works:

var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
options.Converters.Add(new JsonStringEnumConverter());

var batchRequestContent = new BatchRequestContent(GraphClient);
myBatchRequestSteps.ForEach(x => batchRequestContent.AddBatchRequestStep(x));
var batchResponseContent = await GraphClient.Batch.PostAsync(batchRequestContent);
var responces = await batchResponseContent.GetResponsesAsync();
foreach (var responce in responces.Values)
{
var json = await responce.Content.ReadAsStringAsync();
var myEvent = System.Text.Json.JsonSerializer.Deserialize(json, options);
}

@astalmok astalmok changed the title Event's class properties of Enum type failing to deserialize using Latest Microsoft.Graph API version 5.28 Event's class properties of Enum type failing to deserialize using Latest Microsoft.Graph API version 5.1* Oct 17, 2023
@astalmok astalmok changed the title Event's class properties of Enum type failing to deserialize using Latest Microsoft.Graph API version 5.1* Event's class properties of Enum type failing to deserialize using Microsoft.Graph API version 5.1* Oct 17, 2023
@andrueastman
Copy link
Member

Thanks for this @astalmok. We'll close this for now.

Also note that with the latest version of the Microsoft.Graph.Core, you should also be able to use the serialization helper methods available. https://www.nuget.org/packages/Microsoft.Graph.Core/3.1.1

var json = await responce.Content.ReadAsStringAsync();
var derivedType = KiotaJsonSerializer.Deserialize<Event>(json);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants