microsoftgraph / msgraph-sdk-dotnet

Microsoft Graph Client Library for .NET!
https://graph.microsoft.com
Other
703 stars 248 forks source link

[Client bug]: Cannot create an event #2280

Closed fdeola closed 10 months ago

fdeola commented 10 months ago

Cannot create an event because OdataType is inserted by default to Event object A clear and concise description of what the bug is.

To Reproduce Steps to reproduce the behavior:

  1. Create an event object using Graph sdk in .Net

Event evt = new Event {

Subject = $"{meetingType.MeetingTypeTitle} {user.UserDisplayName} and {name}",
Start = startDate.ToDateTimeTimeZone(userTimeZone),
End = endDate.ToDateTimeTimeZone(userTimeZone),
Attendees = new List<Attendee>
{
    new Attendee
    {
        EmailAddress = new EmailAddress
        {
            Address = email,
            Name = name,
        },
        Type = (AttendeeType?)AttendeeType.Required,
    }
},
Body = new ItemBody
{
    ContentType = (BodyType?)BodyType.Text,
    Content = notes,
},
IsReminderOn = true,
ReminderMinutesBeforeStart = meetingType.MeetingTypeBufferBeforeMin,
Sensitivity = Sensitivity.Normal,
Importance = Importance.Normal,
AllowNewTimeProposals = true,
TransactionId = $"MEETING:{Guid.NewGuid()}", // TODO
IsOrganizer = true

};

  1. Send the event to Graph through PostAsync(evt, requestConfiguration)
  2. An exception is encountered "The request is malformed or incorrect: expected a string for ODataType value."

Expected behavior An event will be created in the calendar

Client version 5.38

Additional context When Event object is created, the following properties are automatically added: "AdditionalData" "BackingStore" "OdataType"

When i tried to run the generated json in Graph explorer, the error below is encountered. { "error": { "code": "UnableToDeserializePostBody", "message": "were unable to deserialize " } }

When I removed the following properties from json and execute in graph explorer, an event can be successfully generated. "AdditionalData" "BackingStore" "OdataType"

I want to ask if theses properties are now required to create an event? How can I assign values to these properties that are valid?

andrueastman commented 10 months ago

Thanks for raising this @fdeola

Any chance you can share the method of serialization used to build the request body? Ideally, you should use this are the models use a custom serializer and won't omit or properly serilialize otherwise.

var json = KiotaJsonSerializer.SerializeAsString(eventItem);
fdeola commented 10 months ago

Here is my scenarion.

WebAssembly:

  1. Create event

Event evt = new Microsoft.Graph.Models.Event{ Subject = $"{meetingType.MeetingTypeTitle} {user.UserDisplayName} and {name}", Start = startDate.ToDateTimeTimeZone(userTimeZone), End = endDate.ToDateTimeTimeZone(userTimeZone), Attendees = new List<Attendee> { new Attendee { EmailAddress = new EmailAddress { Address = email, Name = name, }, Type = (AttendeeType?)AttendeeType.Required, } }, Body = new ItemBody { ContentType = (BodyType?)BodyType.Text, Content = notes, }, IsReminderOn = true, ReminderMinutesBeforeStart = meetingType.MeetingTypeBufferBeforeMin, Sensitivity = Sensitivity.Normal, Importance = Importance.Normal, AllowNewTimeProposals = true, TransactionId = $"MEETING:{Guid.NewGuid()}", // TODO IsOrganizer = true }

  1. Pass it to controller

Blazor Server:

  1. Create the event in MS Graph using PostAsync()

var e = await _graphServiceClient.Users[id].Events.PostAsync(evt, requestConfiguration => requestConfiguration.Headers.Add("Prefer", "IdType=\"ImmutableId\""));

PostAsync needed the Microsoft.Graph.Models.Event as parameter. image

Do you have a scenario where I can make use of serialization here?

Thank you.

fdeola commented 10 months ago

Its a little bit weird that I need to change data back and forth just to make it work.

var json = KiotaJsonSerializer.SerializeAsString(evt);
var jsonParseNode = new JsonParseNode(JsonDocument.Parse(json).RootElement);
Event m = jsonParseNode.GetObjectValue(Event.CreateFromDiscriminatorValue)

The Event.Body value is lost during this process.

andrueastman commented 10 months ago

Just to confirm @fdeola, is the Server receiving the created object as json? or as an Event object? My initial understanding was that you wished to serialize the object you initialized.

If so serialization/deserialization can be done as

            var json = KiotaJsonSerializer.SerializeAsString(eventItem);// serialize to string
            Event? newEvent = KiotaJsonSerializer.Deserialize<Event>(json); // deserialize from string.
fdeola commented 10 months ago

@andrueastman The server is receiving the created object as Event object. But the created Event object will get an error when sent to GraphClient.

What I did to resolve the issue as stated above was to serialize and deserialize the data back and forth before sending using the GraphClient and somehow it works.