In this example I am calling the Canvas LMS API to get a list of enrolled students, including their grades, for a specific course.
[topads][/topads]
A little background, if you try to call the Canvas API client side (JavaScript), you will get a CORS Same Origin Policy error: No ‘Access-Control-Allow-Origin’, I tried it 🙁 . So use server-side code, this is where C# comes into place 🙂
Back to C#…To accomplish this I am making use of RestSharp as it is really easy to make API calls with this library.
Since I want to get a list of students for a specific course, I need to use List users in course API call.
GET /api/v1/courses/:course_id/users
Now, since in my custom web application I do not have the Canvas given :course_id, I can make use of the SIS ID as as outlined in Object IDs, SIS IDs, and special IDs since I have that available. And I end up with the API call looking like this
GET /api/v1/courses/sis_course_id:/users
This call will bring back the list of users I need, each of them being an User Object. At this point, if I make the call like this, I will get back teacher[s], student[s], student_view[s], ta[s], observer[s] and, designer[s], so to filter out for ONLY students, I need to add enrollment_type[] to the call.
GET /api/v1/courses/sis_course_id:/users?enrollment_type[]=student
But wait, I also need their grades, so I need to add include[]=enrollments to the call, which will bring the course information including grades.
GET /api/v1/courses/sis_course_id:/users?enrollment_type[]=student&include[]=enrollments
By default Canvas limits the response to 10 users, so adding per_page parameter allows me to specify more users in the response. I chose to bring back “1000” users since we will never have more than 1000 users in a course. See Pagination.
Now the API call looks like this
GET /api/v1/courses/sis_course_id:/users?enrollment_type[]=student&include[]=enrollments&per_page=1000
Last, but not least, and the most important, AUTHENTICATION 🙂 Depending on your needs you can either generate an Access Token (Manual Token Generation) or use their OAuth2. In my case I generated an Access Token and use that every time.
The access token will need to be included in the API call like this
GET /api/v1/courses/sis_course_id:/users?enrollment_type[]=student&include[]=enrollments&per_page=1000&access_token=
Now that I finally have what I need from Canvas, it’s time for some C# code!!
Side note: Before writing your app, play with the Canvas API as described in the Getting Started With The Api page.
Models
You will need three C# Models (or Classes).
These models represent the User Object, Enrollment Object and Grade Object. And depending on your needs, you can omit properties from each object.
User Model
public class User { public int id { get; set; } public string name { get; set; } public string sis_user_id { get; set; } public string login_id { get; set; } public List<Enrollment> enrollments { get; set; } }
Enrollment Model
public class Enrollment { public int user_id { get; set; } public int course_id { get; set; } public string enrollment_state { get; set; } public string sis_course_id { get; set; } public List<Grade> grades { get; set; } }
Grade Model
public class Grade { public float? current_score { get; set; } public float? current_grade { get; set; } public float? final_score { get; set; } public float? final_grade { get; set; } }
Canvas API Class
This class wil consume your Canvas API call
public static class CanvasAPI { const string token = "<ACCESS-TOKEN>"; const string domain = "YOURDOMAIN.instructure.com"; public static List < User > GetUsersInCourse(string sisCourseId) { string url = $ "https://{domain}/api/v1/courses/sis_course_id:{sisCourseId}/users?enrollment_type[]=student&include[]=enrollments&per_page=1000&access_token={token}"; var restClient = new RestClient(url); var request = new RestRequest(Method.GET); var response = restClient.Execute<List<User>>(request); return response.Data; } }
Don’t forget to install RestSharp via Nuget package and include it in your class.
using RestSharp;
Controller
Inside your controller call the CanvasAPI class.
[Authorize] public ActionResult GetCanvasUsers() { List<User> canvasusers = GetUsersInCourse(sisCourseId); }
JSON Response
The JSON response that results from the Canvas API call looks like this
[ { "id": 177, "name": "John Doe", "sortable_name": "Doe, John", "short_name": "John Doe", "sis_user_id": "109752", "integration_id": null, "sis_login_id": "johndoe@gmail.com", "sis_import_id": 573, "login_id": "johndoe@gmail.com", "enrollments": [ { "id": 350, "user_id": 177, "course_id": 61, "type": "StudentEnrollment", "created_at": "2015-09-28T14:42:38Z", "updated_at": "2015-12-16T05:10:06Z", "associated_user_id": null, "start_at": null, "end_at": null, "course_section_id": 54, "root_account_id": 1, "limit_privileges_to_course_section": false, "enrollment_state": "active", "role": "StudentEnrollment", "role_id": 3, "last_activity_at": "2015-09-30T15:39:33Z", "total_activity_time": 864, "sis_import_id": 1368, "grades": { "html_url": "https://YOURDOMAIN.instructure.com/courses/61/grades/177", "current_score": null, "current_grade": null, "final_score": 0, "final_grade": null }, "sis_account_id": null, "sis_course_id": "44565", "course_integration_id": null, "sis_section_id": "58248", "section_integration_id": null, "sis_user_id": "109752", "html_url": "https://YOURDOMAIN.instructure.com/courses/61/users/177" } ], "analytics_url": "/courses/61/analytics/users/177" } ]
That’s it. Share this post if you liked it.
[bottomads][/bottomads]
Getting data using access token will not work in real time. We have to go with OAuth process. Could you please guide m how to do this OAuth process?
Sorry, but I did not implement OAuth2 flow so I do not have all that entails for this, however you could follow their docs on Oauth2 Flow