Search code examples
c#postoffice365microsoft-graph-apioutlook-restapi

Post events to Microsoft Graph c#


sorry for the multiple posts, I can't get a post request to Microsoft Graph to work, I'm following this documentation, I'm trying to create an event in

https://graph.microsoft.com/beta/myDomain/users/myEmail/calendar/events

I have a function and some helper classes to create the json object like so:

List<ToOutlookCalendar> toOutlook = new List<ToOutlookCalendar>();    
toOutlook.Add(new ToOutlookCalendar
        {
            Start = new End
            {
                DateTime = DateTimeOffset.UtcNow,
                TimeZone = "Pacific Standard Time"
            },
            End = new End
            {
                DateTime = DateTimeOffset.UtcNow,
                TimeZone = "Pacific Standard Time"
            },
            Body = new Body
            {
                ContentType = "HTML",
                Content = "testar for att se skit"
            },
            Subject = "testin",
            Attendees = new List<Attendee>
            {
                new Attendee
                {
                    EmailAddress = new EmailAddress
                    {
                        Address = "myEmail",
                        Name = "name"
                    },
                    Type = "Required"

                }

            },
            Token = tokenn

        });

        return new JsonResult
        {
            Data = toOutlook

        };

previously I was posting to: https://outlook.office.com/api/v2.0/myDomain/users/myEmail/calendar/events

which gave me an error 401, complaining about the token being to week. I created an x509 certificate but had no luck finding a way to upload it to my directory in azure and since I want to do everything programmatically and have succeeded so far and decided to take another approach and came upon the Microsoft graph documentation again.

I get my calendar events from after having authorized the application permissions for Calendars.ReadWrite: https://graph.microsoft.com/beta/myDomain/users/myEmail/calendar/events.

Anyhow my request looks like this and gives me a 400 Bad Request:

htttpclient.DefaultRequestHeaders.Add("Authorization", "Bearer " + tokenn);
htttpclient.DefaultRequestHeaders.Add("Host", "graph.microsoft.com");
htttpclient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var stringPayload = await Task.Run(() => JsonConvert.SerializeObject(res));

var response = await htttpclient.PostAsync($"https://graph.microsoft.com/beta/{myDomain}/users/{myEmail}/calendar/events",
new StringContent(stringPayload, Encoding.UTF8, "application/json"));

Does anyone have any idea why? I'm following the documentation to the letter i believe but still get a 400 bad request.

Edit 1

I use these classes to create the event based on the documentation

 public class ToOutlookCalendar
    {
        [JsonProperty("Subject")]
        public string Subject { get; set; }

        [JsonProperty("Body")]
        public Body Body { get; set; }

        [JsonProperty("Start")]
        public End Start { get; set; }

        [JsonProperty("End")]
        public End End { get; set; }

        [JsonProperty("Attendees")]
        public List<Attendee> Attendees { get; set; }
    }

    public class Attendee
    {
        [JsonProperty("EmailAddress")]
        public EmailAddress EmailAddress { get; set; }

        [JsonProperty("Type")]
        public string Type { get; set; }
    }

    public class EmailAddress
    {
        [JsonProperty("Address")]
        public string Address { get; set; }

        [JsonProperty("Name")]
        public string Name { get; set; }
    }

    public class Body
    {
        [JsonProperty("ContentType")]
        public string ContentType { get; set; }

        [JsonProperty("Content")]
        public string Content { get; set; }
    }

    public class End
    {
        [JsonProperty("DateTime")]
        public DateTimeOffset DateTime { get; set; }

        [JsonProperty("TimeZone")]
        public string TimeZone { get; set; }
    }

Any help is appreciated!!


Solution

  • To make this a little shorter/summarize this is what i use to create an event and is necessary.

    using (HttpClient c = new HttpClient())
    {
         String requestURI = "https://graph.microsoft.com/v1.0/users/"+userEmail+"/calendar/events.";
    
         //with your properties from above except for "Token"
         ToOutlookCalendar toOutlookCalendar = new ToOutlookCalendar();
    
         HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(toOutlookCalendar), Encoding.UTF8, "application/json");
    
         HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestURI);
         request.Content = httpContent;
         //Authentication token
         request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
    
         var response = await c.SendAsync(request);
         var responseString = await response.Content.ReadAsStringAsync();
    }
    

    You don't need these headers:

    htttpclient.DefaultRequestHeaders.Add("Host", "graph.microsoft.com");
    htttpclient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    

    And Token is not Part of an Event object so you should remove it from ToOutlookCalendar.

    If you don't want to write all these JSONObjects yourself all the time you can use the Graph SDK for c# (also eliminates the risk that you forget a property/add a wrong one). They already have an object for Appointments called Event.

    Edit

    You also don't need the "myDomain" part in your request URL.