Jerry
Jerry

Reputation: 149

HttpProvider.SendAsync() Null Content

I am trying to build a small app in C# to retrieve suggested meeting times from the Microsoft Graph API. After authenticating, I call graphClient.HttpProvider.SendAsync(t); to hopefully get suggested meeting times. However, stepping through with breakpoints everything seems to go fine until that call and then the FindMeetingTimes request content is empty/null.

Calling with: eventsService.RunAsync();

internal async Task RunAsync()
    {
        try
        {

            // Create request object
            var findMeetingTimeRequest = new FindMeetingTimeRequestModel
            {
                Attendees = new List<AttendeeBase>
                {
                    new AttendeeBase
                    {
                        EmailAddress = new EmailAddress {Address = "[email protected]" },
                        Type = AttendeeType.Required
                    }
                },
                LocationConstraint = new LocationConstraint
                {
                    IsRequired = true,
                    SuggestLocation = false,
                    Locations = new List<LocationItemModel>
                {
                    new LocationItemModel{ DisplayName = "A116", Address = null, Coordinates = null }
                }
                },
                TimeConstraint = new TimeConstraintModel
                {
                    TimeSlots = new List<TimeSlotModel>
                {
                    new TimeSlotModel
                    {
                        Start = new DateTimeValueModel
                        {
                            Date = "2018-03-23",
                            Time = "08:00:00",
                            TimeZone = "Central Standard Time"
                        },
                        End = new DateTimeValueModel
                        {
                            Date = "2018-03-23",
                            Time = "09:00:00",
                            TimeZone = "Central Standard Time"
                        }
                    }
                }
                },
                MeetingDuration = new Duration("PT1H"),
                MaxCandidates = 99,
                IsOrganizerOptional = false,
                ReturnSuggestionHints = false
            };

            GraphServiceClient graphClient = SDKHelper.GetAuthenticatedClient();

            var t = graphClient.Me.FindMeetingTimes(findMeetingTimeRequest.Attendees, findMeetingTimeRequest.LocationConstraint, findMeetingTimeRequest.TimeConstraint, findMeetingTimeRequest.MeetingDuration, findMeetingTimeRequest.MaxCandidates, findMeetingTimeRequest.IsOrganizerOptional).Request().GetHttpRequestMessage();

            await graphClient.AuthenticationProvider.AuthenticateRequestAsync(t);

            var response = await graphClient.HttpProvider.SendAsync(t);
            var jsonString = await response.Content.ReadAsStringAsync();

            Console.WriteLine(jsonString);
            return;
        }catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
            return;
        }
    }

I'm sort of at a loss as to what to try next. I have looked through examples and there's only a handful out there so far that use GraphServiceClient/SDKHelper to authenticate. Could this be part of the problem?

I get both exceptions during await graphClient.HttpProvider.SendAsync(t);:

Exception thrown: 'Microsoft.Graph.ServiceException' in Microsoft.Graph.Core.dll

Exception thrown: 'System.NullReferenceException' in System.Web.dll


Update: Using both the reference in Michael's comment below and the original code with an empty argument list for FindMeetingTimes(), I'm getting a credentials exception: "Code: ErrorAccessDenied\r\nMessage: Access is denied. Check credentials and try again.\r\n\r\nInner error\r\n"

Calling with await eventsService.EventFindMeetingsTimes(graphClient);

public async System.Threading.Tasks.Task EventFindMeetingsTimes(GraphServiceClient graphClient)
    {
        try
        {
            User me = await graphClient.Me.Request().GetAsync();

            // Get the first three users in the org as attendees unless user is the organizer.
            var orgUsers = await graphClient.Users.Request().GetAsync();
            List<Attendee> attendees = new List<Attendee>();
            Attendee attendee = new Attendee();
            attendee.EmailAddress = new EmailAddress();
            attendee.EmailAddress.Address = "[email protected]";
            attendees.Add(attendee);

            // Create a duration with an ISO8601 duration.
            Duration durationFromISO8601 = new Duration("PT1H");
            MeetingTimeSuggestionsResult resultsFromISO8601 = await graphClient.Me.FindMeetingTimes(attendees,
                                                                                                        null,
                                                                                                        null,
                                                                                                        durationFromISO8601,
                                                                                                        2,
                                                                                                        true,
                                                                                                        false,
                                                                                                        10.0).Request().PostAsync();
            List<MeetingTimeSuggestion> suggestionsFromISO8601 = new List<MeetingTimeSuggestion>(resultsFromISO8601.MeetingTimeSuggestions);
        }
        catch (Exception e)
        {
            Console.WriteLine("Something happened, check out a trace. Error code: {0}", e.Message);
        }
    }

The account I'm using to log in works when I test with the GraphExplorer. Is it possible the credentials/token aren't being passed down through the web form and into the graph client?


SOLUTION: Graph Docs example <-- Provided by Michael helped set up the formatting correctly. Find meeting times problem #559 <-- Tipped off by Marc that the permissions in the end needed updated and eventually solved my updated problem.

Upvotes: 2

Views: 1751

Answers (2)

Michael Mainer
Michael Mainer

Reputation: 3475

You forgot to set the HttpMethod before SendAsync(t). It is using GET instead of POST.

t.Method = System.Net.Http.HttpMethod.Post;

With that said, I agree with Mark. Use the built in functionality of the client library:

https://github.com/microsoftgraph/msgraph-sdk-dotnet/blob/dev/tests/Microsoft.Graph.Test/Requests/Functional/EventTests.cs#L88

Upvotes: 3

Marc LaFleur
Marc LaFleur

Reputation: 33124

Without more detail, it is difficult to determine what is going wrong here. That said, you should start with simplifying this code. That will at least reduce the number of moving parts:

var result = await graphClient.Me.FindMeetingTimes()
    .Request()
    .PostAsync();

if (!string.IsNullOrWhiteSpace(result.EmptySuggestionsReason))
{
    Console.WriteLine(result.EmptySuggestionsReason);
}
else
{
    foreach (var item in result.MeetingTimeSuggestions)
    {
        Console.WriteLine($"Suggestion: {item.SuggestionReason}");
    }
}

If this fails, be sure to capture the entire exception and update your question.

Upvotes: 1

Related Questions