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