1

I am trying to create an event by posting to the Microsoft Graph API (using c#). However, every time I am getting a bad request (400) response. The reason I dont want to use the Graph Client is because Im going to be putting it into an old project targeting .NET Framework 452.

In my demo app (for time being, im pulling in the Microsoft.Graph library, just to be able to use Event Class - but will create my own down the line).

// webApiUrl = https://graph.microsoft.com/v1.0/users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx/calendar/events
// request = this has been populated with minimum event details (i.e. subject, start, end, attendees etc)
// accessToken = this is working correctly - tested on other calls

public async Task PostToWebApiAndProcessResultASync(string webApiUrl, Event request, string accessToken, Action<JObject> processResult)
        {
            if (!string.IsNullOrEmpty(accessToken))
            {
                var defaultRequestHeaders = HttpClient.DefaultRequestHeaders;
                if (defaultRequestHeaders.Accept == null || !defaultRequestHeaders.Accept.Any(m => m.MediaType == "application/json"))
                {
                    HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                }
                defaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

                string json = JsonConvert.SerializeObject(request);

                StringContent httpContent = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

                HttpResponseMessage response = await HttpClient.PostAsync(webApiUrl, httpContent);

                if (response.IsSuccessStatusCode)
                {
                    string responseJson = await response.Content.ReadAsStringAsync();
                    JObject result = JsonConvert.DeserializeObject(responseJson) as JObject;
                    Console.ForegroundColor = ConsoleColor.Gray;
                    processResult(result);
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine($"Failed to call the web API: {response.StatusCode}");
                    string content = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Content: {content}");
                }
                Console.ResetColor();
            }
        }

Looking at the API Specification here: https://learn.microsoft.com/en-us/graph/api/user-post-events?view=graph-rest-1.0&tabs=http

It looks to me like I am posting to the correct end point, attaching the correct headers (bearer and content-type) and also sending the body as JSON.

Any suggestions on why this code would return a 400 error would be much appreciated:

{StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
  Date: Mon, 08 Nov 2021 20:35:51 GMT
  Cache-Control: private
  Transfer-Encoding: chunked
  Strict-Transport-Security: max-age=31536000
  request-id: 465c6c4a-9668-4c8e-8390-9344c865dc8f
  client-request-id: 465c6c4a-9668-4c8e-8390-9344c865dc8f
  x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"UK South","Slice":"E","Ring":"3","ScaleUnit":"002","RoleInstance":"LO1PEPF000003B3"}}
  Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; IEEE754Compatible=false; charset=utf-8
}}

EDIT

The code below is what I am using to generate the Event Object:

var newEvent  = new Event();
newEvent.Subject = "Test event from console app";
newEvent.Body = new ItemBody()
{
    ContentType = BodyType.Html,
    Content = "<html><body><p>Does late morning work for you?</p></body></html>"
};
newEvent.Start = new DateTimeTimeZone() {
    DateTime = "2021-11-08T20:00:00",
    TimeZone = "Pacific Standard Time"
};
newEvent.End = new DateTimeTimeZone()
{
    DateTime = "2021-11-08T22:00:00",
    TimeZone = "Pacific Standard Time"
};
newEvent.Location = new Location() { 
    DisplayName="Deepdale"
};
newEvent.Attendees = new List<Attendee>() { 
    new Attendee(){ 
        EmailAddress= new EmailAddress()
        { 
            Address="xxxx.xxxx@xxxxxxxx.ac.uk",
            Name="Nicki"
        },
        Type=AttendeeType.Required
    }
};

Json that is generated from the Event object:

"{\"AllowNewTimeProposals\":null,\"Attendees\":[{\"ProposedNewTime\":null,\"Status\":null,\"Type\":0,\"EmailAddress\":{\"Address\":\"xxxx.xxx@xxxxxxxx.ac.uk\",\"Name\":\"Nicki\",\"AdditionalData\":null,\"ODataType\":null},\"AdditionalData\":null,\"ODataType\":\"microsoft.graph.attendee\"}],\"Body\":{\"Content\":\"<html><body><p>Does late morning work for you?</p></body></html>\",\"ContentType\":1,\"AdditionalData\":null,\"ODataType\":null},\"BodyPreview\":null,\"End\":{\"DateTime\":\"2021-11-08T22:00:00\",\"TimeZone\":\"Pacific Standard Time\",\"AdditionalData\":null,\"ODataType\":null},\"HasAttachments\":null,\"HideAttendees\":null,\"ICalUId\":null,\"Importance\":null,\"IsAllDay\":null,\"IsCancelled\":null,\"IsDraft\":null,\"IsOnlineMeeting\":null,\"IsOrganizer\":null,\"IsReminderOn\":null,\"Location\":{\"Address\":null,\"Coordinates\":null,\"DisplayName\":\"Deepdale\",\"LocationEmailAddress\":null,\"LocationType\":null,\"LocationUri\":null,\"UniqueId\":null,\"UniqueIdType\":null,\"AdditionalData\":null,\"ODataType\":null},\"Locations\":null,\"OnlineMeeting\":null,\"OnlineMeetingProvider\":null,\"OnlineMeetingUrl\":null,\"Organizer\":null,\"OriginalEndTimeZone\":null,\"OriginalStart\":null,\"OriginalStartTimeZone\":null,\"Recurrence\":null,\"ReminderMinutesBeforeStart\":null,\"ResponseRequested\":null,\"ResponseStatus\":null,\"Sensitivity\":null,\"SeriesMasterId\":null,\"ShowAs\":null,\"Start\":{\"DateTime\":\"2021-11-08T20:00:00\",\"TimeZone\":\"Pacific Standard Time\",\"AdditionalData\":null,\"ODataType\":null},\"Subject\":\"Test event from console app\",\"TransactionId\":null,\"Type\":null,\"WebLink\":null,\"Attachments\":null,\"AttachmentsNextLink\":null,\"Calendar\":null,\"Extensions\":null,\"ExtensionsNextLink\":null,\"Instances\":null,\"InstancesNextLink\":null,\"MultiValueExtendedProperties\":null,\"MultiValueExtendedPropertiesNextLink\":null,\"SingleValueExtendedProperties\":null,\"SingleValueExtendedPropertiesNextLink\":null,\"Categories\":null,\"ChangeKey\":null,\"CreatedDateTime\":null,\"LastModifiedDateTime\":null,\"Id\":null,\"ODataType\":\"microsoft.graph.event\",\"AdditionalData\":null}"

Dean

Dean O'Brien
  • 335
  • 2
  • 11
  • https://stackoverflow.com/questions/19671317/400-bad-request-http-error-code-meaning - I think your events that are being wrapped up in your call are maybe malformed. It'd be helpful to capture what the ```request``` object looks like. – Rrrrrr Nov 08 '21 at 21:11
  • Thanks for getting back to me Rrrrrr, I have updated the question to show the Event objects creation and also its state after conversion to JSON. – Dean O'Brien Nov 09 '21 at 08:19

0 Answers0