microsoft-graph-apimicrosoft-graph-edu

How to print feedback and points using Graph API?


I created a function to return the outcomes using Microsoft Graph Education API. I want to print feedback and points but I can’t, they don’t exist. Here is the code:

public static async Task<IEnumerable<EducationOutcome>> GetOutcomesForSubmission()
{
  var outcomes = await graphClient
    .Education
    .Classes["8557483b-a233-4710-82de-e1bdb03bb9a9"]
    .Assignments["1b09cd43-cf87-4cef-a043-ae3d6160c200"]
    .Submissions["d4486e20-1b47-4b5b-720c-0fe0038d4882"]
    .Outcomes
    .Request()
    .GetAsync();

  return outcomes;
}

public static void ListOutcomes()
{
  var outcomes = GetOutcomesForSubmission().Result;

  Console.WriteLine("Outcomes:\n");

  foreach (var v in outcomes)
  {
    Console.WriteLine($"User id: {v.LastModifiedBy.User.Id}, Submission id: {v.Id}");
  }

  Console.WriteLine("\n");
}

Solution

  • Your issue is that GetAsync() isn't returning a collection of EducationOutcome objects. It is returning an EducationSubmissionOutcomesCollectionPage instead. To get the actual results, you need to return the CurrentPage property.

    public static async Task<IEnumerable<EducationOutcome>> GetOutcomesForSubmission()
    {
      var response = await graphClient
        .Education
        .Classes["8557483b-a233-4710-82de-e1bdb03bb9a9"]
        .Assignments["1b09cd43-cf87-4cef-a043-ae3d6160c200"]
        .Submissions["d4486e20-1b47-4b5b-720c-0fe0038d4882"]
        .Outcomes
        .Request()
        .GetAsync();
    
      return response.CurrentPage.ToList();
    }
    

    Note that this will only return the first page of data. If you want to grab all of the data, you'll need to page through using the response.NextPageRequest property:

    var outcomes = response.CurrentPage.ToList();
    while (response.NextPageRequest != null)
    {
        response = await response.NextPageRequest.GetAsync();
        outcomes.AddRange(response.CurrentPage);
    
    }
    return outcomes;
    

    Keep in mind that EducationOutcome is a base class, so it will only contain properties common across all "Outcome" types (which in this case is pretty little). If you want a specific type of Outcome, you'll need to cast it to the specific type first:

    foreach (var v in outcomes)
    {
      if (v is EducationRubricOutcome)
      {
        var outcome = v as EducationRubricOutcome;
        Console.WriteLine($"User id: {outcome.LastModifiedBy.User.Id}, Submission id: {outcome.Id}, Feedback Count: {outcome.RubricQualityFeedback.Count}");
      }
      else if (v is EducationPointsOutcome)
      {
        var outcome = v as EducationPointsOutcome;
        Console.WriteLine($"User id: {outcome.LastModifiedBy.User.Id}, Submission id: {outcome.Id}, Points: {outcome.Points.Points}");
      }
      else if (v is EducationFeedbackOutcome)
      {
        var outcome = v as EducationFeedbackOutcome;
        Console.WriteLine($"User id: {outcome.LastModifiedBy.User.Id}, Submission id: {outcome.Id}, Feedback: {outcome.Feedback.Text}");
      }
    }