public RubricViewModel() { Rubric = new Rubric(); _MergedEvaluations = new List <RubricEvaluation>(); Evaluation = new RubricEvaluation(); SelectedSection = 0; Completed = false; isMerged = false; }
public override DynamicDictionary BuildHeader(Assignment assignment) { dynamic header = Builder.BuildHeader(assignment); header.AssignmentDetails = new DynamicDictionary(); RubricEvaluation rubricEvaluation = null; //Getting the assignment team for Student, and if its non-null then we take that team ID and find the RubricEvaluation //that they were the recipient of. AssignmentTeam at = OSBLEController.GetAssignmentTeam(assignment, Student); int teamId = 0; if (at != null) { teamId = at.TeamID; using (OSBLEContext db = new OSBLEContext()) { //Only want to look at evaluations where Evaluator.AbstractRole.CanGrade is true, otherwise //the rubric evaluation is a student rubric (not interested in them here) rubricEvaluation = (from re in db.RubricEvaluations where re.AssignmentID == assignment.ID && re.Evaluator.AbstractRole.CanGrade && re.RecipientID == teamId select re).FirstOrDefault(); } } //If the Rubric has been evaluated and is published, calculate the rubric grade % to display to the student if (rubricEvaluation != null && rubricEvaluation.IsPublished) { header.AssignmentDetails.hasGrade = true; header.AssignmentDetails.assignmentID = assignment.ID; header.AssignmentDetails.cuID = Student.ID; header.AssignmentDetails.DisplayValue = "View Graded Rubric " + RubricEvaluation.GetGradeAsPercent(rubricEvaluation.ID); } else { header.AssignmentDetails.DisplayValue = "Not Graded"; header.AssignmentDetails.hasGrade = false; } return(header); }
/// <summary> /// This function builds the column for Rubric Grades in the instructor assignment details table. Note: This only handles non-student-evaluated rubrics. /// </summary> /// <param name="assignmentTeam"></param> /// <returns></returns> public override DynamicDictionary BuildTableForTeam(IAssignmentTeam assignmentTeam) { Assignment assignment = assignmentTeam.Assignment; dynamic data = Builder.BuildTableForTeam(assignmentTeam); data.Grade = new DynamicDictionary(); data.Grade.ActionValues = new { assignmentId = assignment.ID, cuId = assignmentTeam.Team.TeamMembers.FirstOrDefault().CourseUserID, area = "" }; RubricEvaluation rubricEvaluation = null; using (OSBLEContext db = new OSBLEContext()) { rubricEvaluation = db.RubricEvaluations.Where(re => re.RecipientID == assignmentTeam.TeamID && re.Evaluator.AbstractRole.CanGrade && re.AssignmentID == assignment.ID ).FirstOrDefault(); } data.Grade.LinkText = "Not Graded"; if (rubricEvaluation != null) { //A rubric exists, so if it is not published, it's saved as draft. If it is //published, the rubric grade should be displayed. if (rubricEvaluation.IsPublished == false) { data.Grade.LinkText = "Saved as Draft (" + RubricEvaluation.GetGradeAsPercent(rubricEvaluation.ID) + ")"; } else { data.Grade.LinkText = RubricEvaluation.GetGradeAsPercent(rubricEvaluation.ID); } } return(data); }
public ActionResult ExportAssignmentGrades(int assignmentID) { //get total points for this assignment int totalPoints = DBHelper.GetAssignmentPointTotal(assignmentID); //find all students for current course List <CourseUser> students = (from c in db.CourseUsers where c.AbstractCourseID == ActiveCourseUser.AbstractCourseID && c.AbstractRoleID == (int)CourseRole.CourseRoles.Student select c).ToList(); if (ActiveCourseUser.Section != -2) //instructors or all sections users can download all student grades { List <int> sections = new List <int>(); //need to keep track of multiple sections. if (ActiveCourseUser.Section == -1) //multiple sections { List <string> idList = ActiveCourseUser.MultiSection.Split(',').ToList(); foreach (string id in idList) { int section; if (Int32.TryParse(id, out section)) { sections.Add(section); } } } else { sections.Add(ActiveCourseUser.Section); } // For TAs, make rid of any student that isn't in the TA's section. for (int i = 0; i < students.Count; i++) { if (!sections.Contains(students[i].Section)) { students.RemoveAt(i); i--; } } } //key-value pair for names-grades Dictionary <string, string> grades = new Dictionary <string, string>(); //key-value pair for fullname-lastname so we can sort by lastname when creating the csv Dictionary <string, string> firstLast = new Dictionary <string, string>(); //key-value pair to keep track of the late penalty Dictionary <string, string> latePenalty = new Dictionary <string, string>(); //seed dictionary with student last, first names foreach (CourseUser student in students) { if (!grades.ContainsKey(student.UserProfile.FullName) && !firstLast.ContainsKey(student.UserProfile.FullName) && !latePenalty.ContainsKey(student.UserProfile.FullName)) { grades.Add(student.UserProfile.FullName, ""); firstLast.Add(student.UserProfile.FullName, student.UserProfile.LastName); latePenalty.Add(student.UserProfile.FullName, ""); } } //get graded rubrics List <RubricEvaluation> rubricEvaluations = null; rubricEvaluations = db.RubricEvaluations.Where(re => re.Evaluator.AbstractRole.CanGrade && re.AssignmentID == assignmentID).ToList(); if (rubricEvaluations.Count > 0) //make sure there are rubrics saved { foreach (RubricEvaluation rubricEvaluation in rubricEvaluations) { string rubricStudentName = ""; //we need to go through teams to handle team assignments. this works for individuals because an individual is a team of 1 foreach (var teamMember in rubricEvaluation.Recipient.TeamMembers) { rubricStudentName = teamMember.CourseUser.UserProfile.FullName; if (rubricEvaluation.IsPublished) { //update value to match key if (grades.ContainsKey(rubricStudentName)) { grades[rubricStudentName] = RubricEvaluation.GetGradeAsDouble(rubricEvaluation.ID).ToString(); AssignmentTeam team = new AssignmentTeam(); team.Assignment = rubricEvaluation.Assignment; team.AssignmentID = rubricEvaluation.AssignmentID; team.Team = teamMember.Team; team.TeamID = teamMember.TeamID; latePenalty[rubricStudentName] = (GetLatePenalty(team) / 100.0).ToString(); } } } } //sort the grades A-Z by last name var sortedNameList = from pair in firstLast orderby pair.Value ascending select pair; //make a csv for export var csv = new StringBuilder(); csv.Append(String.Format("{0},{1},{2},{3},{4},{5},{6}{7}", "FirstName", "LastName", "Score(PCT)", "Raw Points out of " + totalPoints.ToString(), "Late Penalty(PCT)", "Score(PCT) - Late Penalty", "Raw Score - Late Penalty", Environment.NewLine)); foreach (KeyValuePair <string, string> pair in sortedNameList) { //place quotes around name so the first, last format doesn't break the csv string firstname = "\"" + pair.Key.Split(' ').ToList().First() + "\""; //split off first name string lastname = "\"" + pair.Value + "\""; string rawScore = String.IsNullOrEmpty(grades[pair.Key]) ? "" : (Convert.ToDouble(grades[pair.Key]) * totalPoints).ToString(); double grade = String.IsNullOrEmpty(grades[pair.Key]) ? -1.0 : Convert.ToDouble(grades[pair.Key]); //string gradePCT = String.IsNullOrEmpty(grades[pair.Key]) ? "" : (Convert.ToDouble(grades[pair.Key]) * 100).ToString(); //string latePentaltyPCT = String.IsNullOrEmpty(latePenalty[pair.Key]) ? "" : (Convert.ToDouble(latePenalty[pair.Key]) * 100).ToString(); string latePentaltyPCT = String.IsNullOrEmpty(latePenalty[pair.Key]) ? "" : (Convert.ToDouble(latePenalty[pair.Key])).ToString(); double latePenaltyScore = String.IsNullOrEmpty(grades[pair.Key]) ? -1.0 : Convert.ToDouble(latePenalty[pair.Key]); string lateScorePCT = String.IsNullOrEmpty(grades[pair.Key]) ? "" : (grade - latePenaltyScore <= 0 ? 0 : grade - latePenaltyScore).ToString(); string lateRawScore = String.IsNullOrEmpty(grades[pair.Key]) ? "" : (grade - latePenaltyScore <= 0 ? 0 : (grade - latePenaltyScore) * totalPoints).ToString(); var newLine = String.Format("{0},{1},{2},{3},{4},{5},{6}{7}", firstname, lastname, grades[pair.Key], rawScore, latePentaltyPCT, lateScorePCT, lateRawScore, Environment.NewLine); csv.Append(newLine); } const string contentType = "text/plain"; var bytes = Encoding.UTF8.GetBytes(csv.ToString()); return(File(bytes, contentType, rubricEvaluations.First().Assignment.AssignmentName + " " + DateTime.Now + " (Exported Grades).csv")); } if (Request.UrlReferrer != null) { return(Redirect(Request.UrlReferrer.ToString())); } else { return(RedirectToAction("Index", "Home", new { area = "AssignmentDetails", assignmentId = assignmentID })); } }
public override DynamicDictionary BuildHeader(Assignment assignment) { dynamic header = Builder.BuildHeader(assignment); header.Submission = new DynamicDictionary(); header.IsAnnotatable = new bool(); header.DeliverableType = assignment.Deliverables.FirstOrDefault().Type; DateTime?submissionTime = null; //get id of current student's team List <TeamMember> allMembers = assignment.AssignmentTeams.SelectMany(at => at.Team.TeamMembers).ToList(); TeamMember member = allMembers.Where(m => m.CourseUserID == Student.ID).FirstOrDefault(); header.Submission.allowSubmit = true; //get submission time: foreach (AssignmentTeam team in assignment.AssignmentTeams) { //if the team matches with the student if (team.TeamID == member.TeamID) { submissionTime = team.GetSubmissionTime(); break; } } if (submissionTime == null) { header.Submission.hasSubmitted = false; } else { header.Submission.hasSubmitted = true; header.Submission.SubmissionTime = submissionTime.Value.ToString(); } header.Submission.assignmentID = assignment.ID; FileCache Cache = FileCacheHelper.GetCacheInstance(OsbleAuthentication.CurrentUser); //Same functionality as in the other controller. //did the user just submit something? If so, set up view to notify user if (Cache["SubmissionReceived"] != null && Convert.ToBoolean(Cache["SubmissionReceived"]) == true) { header.Submission.SubmissionReceived = true; Cache["SubmissionReceived"] = false; } else { header.Submission.SubmissionReceived = false; Cache["SubmissionReceived"] = false; } //handle link for viewing annotated documents RubricEvaluation rubricEvaluation = null; //Getting the assignment team for Student, and if its non-null then we take that team ID and find the RubricEvaluation //that they were the recipient of. AssignmentTeam ateam = OSBLEController.GetAssignmentTeam(assignment, Student); int teamId = 0; if (ateam != null) { teamId = ateam.TeamID; header.Submission.authorTeamID = teamId; using (OSBLEContext db = new OSBLEContext()) { //Only want to look at evaluations where Evaluator.AbstractRole.CanGrade is true, otherwise //the rubric evaluation is a student rubric (not interested in them here) rubricEvaluation = (from re in db.RubricEvaluations where re.AssignmentID == assignment.ID && re.Evaluator.AbstractRole.CanGrade && re.RecipientID == teamId select re).FirstOrDefault(); //if annotatable if (assignment.IsAnnotatable) { //yc: determine if there has been an annotation for this document //there will be an issue with linking from a critical review untill further discussion on how to handle this //when an instructor grades this, the reviewerid of the annoation is the teamid string lookup = assignment.CourseID.ToString() + "-" + assignment.ID.ToString() + "-" + teamId.ToString() + "-"; AnnotateDocumentReference d = (from adr in db.AnnotateDocumentReferences where adr.OsbleDocumentCode.Contains(lookup) select adr).FirstOrDefault(); if (d != null && assignment.DueDate < DateTime.UtcNow) { header.IsAnnotatable = true; } else { header.IsAnnotatable = false; } } else { header.IsAnnotatable = false; } } } //If the Rubric has been evaluated and is published, calculate the rubric grade % to display to the student if (rubricEvaluation != null && rubricEvaluation.IsPublished) { header.IsPublished = true; } else { header.IsPublished = false; } return(header); }
private AssignmentDetailsViewModel BuildHeader(AssignmentDetailsViewModel vm) { //AC NOTE: Items will be displayed in the order in which they are added // to the ViewModel's HeaderViews list. Organize accordingly. Assignment assignment = vm.CurrentAssignment; vm.HeaderBuilder = new DefaultBuilder(); List <TeamEvaluation> teamEvaluations = null; using (OSBLEContext db = new OSBLEContext()) { //only need get these when they are needed if (assignment.Type == AssignmentTypes.TeamEvaluation) { teamEvaluations = db.TeamEvaluations.Where(te => te.TeamEvaluationAssignmentID == assignment.ID).ToList(); } } //views common to both students and teachers: if (assignment.Type == AssignmentTypes.DiscussionAssignment || assignment.Type == AssignmentTypes.CriticalReviewDiscussion) { //add initial / final post due date information //TODO: this will replace the "posts due" row vm.HeaderBuilder = new InitialFinalDueDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("InitialFinalDueDecorator"); } //not a team evaluation assignment if (assignment.Type != AssignmentTypes.TeamEvaluation && assignment.Type != AssignmentTypes.AnchoredDiscussion) { //add late policy vm.HeaderBuilder = new LatePolicyHeaderDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("LatePolicyHeaderDecorator"); } //teacher views //AC NOTE: Investigate the differences between CanGrade and CanModify if (vm.Client.AbstractRole.CanGrade || vm.Client.AbstractRole.CanModify) { //add deliverable information if needed if (assignment.HasDeliverables && assignment.Type != AssignmentTypes.AnchoredDiscussion) { //list deliverables add download link vm.HeaderBuilder = new TeacherDeliverablesHeaderDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("TeacherDeliverablesHeaderDecorator"); } //is a discussion assignment if (assignment.Type == AssignmentTypes.DiscussionAssignment && !assignment.HasDiscussionTeams) { //link to classwide discussion vm.HeaderBuilder = new TeacherDiscussionLinkDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("TeacherDiscussionLinkDecorator"); } if (assignment.HasRubric) { //add link to rubric ViewAsUneditable mode vm.HeaderBuilder = new RubricDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("RubricDecorator"); //Show rubric grading progress for assignments with rubrics vm.HeaderBuilder = new RubricGradingProgressDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("RubricGradingProgressDecorator"); } if (assignment.Type == AssignmentTypes.TeamEvaluation) { //Show progress of TeamEvaluation, such as "X of Y Team Evaluations completed" vm.HeaderBuilder = new TeamEvalProgressDecorator(vm.HeaderBuilder, teamEvaluations); vm.HeaderViews.Add("TeamEvalProgressDecorator"); } else if (assignment.Type == AssignmentTypes.CriticalReview) { vm.HeaderBuilder = new PublishCriticalReviewDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("PublishCriticalReviewDecorator"); } else if (assignment.Type == AssignmentTypes.AnchoredDiscussion) { //commented out: for now we don't need anything here for the instructor //in future implementations we may want to let the instructor also review documents with the group, but //how the teams are set up currently it wont work (no team set up for instructor) //link for critical review submission document //vm.HeaderBuilder = new AnchoredDiscussionSubmitDecorator(vm.HeaderBuilder, vm.Client); //vm.HeaderViews.Add("AnchoredDiscussionSubmitDecorator"); } // ABET outcomes - the ABETDepartment property being non-null indicates that // this assignment was labeled for ABET outcomes and assessment. if (null != assignment.ABETDepartment) { vm.HeaderBuilder = new ABETOutcomesDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("ABETOutcomesDecorator"); } } else if (vm.Client.AbstractRoleID == (int)OSBLE.Models.Courses.CourseRole.CourseRoles.Observer) { //has discussion teams? if (assignment.HasDiscussionTeams) { vm.HeaderBuilder = new DiscussionTeamMemberDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("DiscussionTeamMemberDecorator"); } if (assignment.HasRubric) { //add link to rubric ViewAsUneditable mode vm.HeaderBuilder = new RubricDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("RubricDecorator"); } if (assignment.HasDeliverables && assignment.Type != AssignmentTypes.AnchoredDiscussion) { //list deliverables add download link vm.HeaderBuilder = new TeacherDeliverablesHeaderDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("TeacherDeliverablesHeaderDecorator"); } else if (assignment.Type == AssignmentTypes.DiscussionAssignment && !assignment.HasDiscussionTeams) { //link to classwide discussion vm.HeaderBuilder = new StudentDiscussionLinkDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("StudentDiscussionLinkDecorator"); } else if (assignment.Type == AssignmentTypes.CriticalReview) { vm.HeaderBuilder = new TeacherDeliverablesHeaderDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("TeacherDeliverablesHeaderDecorator"); } } else if (vm.Client.AbstractRole.CanSubmit) //students { DateTime due = assignment.DueDate.AddHours(assignment.HoursLateWindow); due = due.UTCToCourse(vm.Client.AbstractCourseID); DateTime now = DateTime.UtcNow; now = now.UTCToCourse(vm.Client.AbstractCourseID); bool canSub = (now < due); //has discussion teams? if (assignment.HasDiscussionTeams) { vm.HeaderBuilder = new DiscussionTeamMemberDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("DiscussionTeamMemberDecorator"); } else if (assignment.HasTeams)//else has teams? { // add team name and list of members vm.HeaderBuilder = new TeamMembersDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("TeamMembersDecorator"); } //needs to submit? if (assignment.HasDeliverables) { if (assignment.Type == AssignmentTypes.AnchoredDiscussion) { //link for critical review submission document vm.HeaderBuilder = new AnchoredDiscussionSubmissionDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("AnchoredDiscussionSubmissionDecorator"); } else { //add student submission link vm.HeaderBuilder = new StudentSubmissionDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("StudentSubmissionDecorator"); } } else if (assignment.Type == AssignmentTypes.CriticalReview) { //critical review submission link vm.HeaderBuilder = new CriticalReviewSubmissionDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("CriticalReviewSubmissionDecorator"); //link for student to download their reviewed assignment vm.HeaderBuilder = new CriticalReviewStudentDownloadDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("CriticalReviewStudentDownloadDecorator"); } else if (assignment.Type == AssignmentTypes.AnchoredDiscussion) { //link for critical review submission document vm.HeaderBuilder = new AnchoredDiscussionSubmissionDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("AnchoredDiscussionSubmissionDecorator"); } else if (assignment.Type == AssignmentTypes.DiscussionAssignment && !assignment.HasDiscussionTeams) { //link to classwide discussion vm.HeaderBuilder = new StudentDiscussionLinkDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("StudentDiscussionLinkDecorator"); } else if (assignment.Type == AssignmentTypes.TeamEvaluation && canSub) { vm.HeaderBuilder = new StudentTeamEvalSubmissionDecorator(vm.HeaderBuilder, teamEvaluations, vm.Client); vm.HeaderViews.Add("StudentTeamEvalSubmissionDecorator"); } //rubric? if (assignment.HasRubric) { RubricEvaluation rubricEvaluation = null; //Getting the assignment team for Student, and if its non-null then we take that team ID and find the RubricEvaluation //that they were the recipient of. AssignmentTeam at = OSBLEController.GetAssignmentTeam(assignment, vm.Client); int teamId = 0; if (at != null) { teamId = at.TeamID; using (OSBLEContext db = new OSBLEContext()) { //Only want to look at evaluations where Evaluator.AbstractRole.CanGrade is true, otherwise //the rubric evaluation is a student rubric (not interested in them here) rubricEvaluation = (from re in db.RubricEvaluations where re.AssignmentID == assignment.ID && re.Evaluator.AbstractRole.CanGrade && re.RecipientID == teamId select re).FirstOrDefault(); } } //add rubric link if (rubricEvaluation == null) { vm.HeaderBuilder = new RubricDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("RubricDecorator"); } //add link to graded rubric link else { vm.HeaderBuilder = new RubricGradeDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("RubricGradeDecorator"); } } } else if (vm.Client.AbstractRoleID == (int)CourseRole.CourseRoles.Moderator) //Moderator decorators { //has discussion teams? if (assignment.HasDiscussionTeams) { vm.HeaderBuilder = new DiscussionTeamMemberDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("DiscussionTeamMemberDecorator"); } else if (assignment.Type == AssignmentTypes.DiscussionAssignment && !assignment.HasDiscussionTeams) { //link to classwide discussion vm.HeaderBuilder = new StudentDiscussionLinkDecorator(vm.HeaderBuilder, vm.Client); vm.HeaderViews.Add("StudentDiscussionLinkDecorator"); } } if (assignment.Type == AssignmentTypes.CriticalReview || assignment.Type == AssignmentTypes.CriticalReviewDiscussion || assignment.Type == AssignmentTypes.TeamEvaluation) { vm.HeaderBuilder = new PreviousAssignmentDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("PreviousAssignmentDecorator"); } if (assignment.Type == AssignmentTypes.CriticalReviewDiscussion && vm.Client.AbstractRole.CanGrade) { vm.HeaderBuilder = new DownloadDiscussionItemsDecorator(vm.HeaderBuilder); vm.HeaderViews.Add("DownloadDiscussionItemsDecorator"); } return(vm); }
public ActionResult ExportAssignmentGrades(int assignmentID) { //find all students for current course List <CourseUser> students = (from c in db.CourseUsers where c.AbstractCourseID == ActiveCourseUser.AbstractCourseID && c.AbstractRoleID == (int)CourseRole.CourseRoles.Student select c).ToList(); if (ActiveCourseUser.Section != -2) //instructors or all sections users can download all student grades { List <int> sections = new List <int>(); //need to keep track of multiple sections. if (ActiveCourseUser.Section == -1) //multiple sections { List <string> idList = ActiveCourseUser.MultiSection.Split(',').ToList(); foreach (string id in idList) { int section; if (Int32.TryParse(id, out section)) { sections.Add(section); } } } else { sections.Add(ActiveCourseUser.Section); } // For TAs, make rid of any student that isn't in the TA's section. for (int i = 0; i < students.Count; i++) { if (!sections.Contains(students[i].Section)) { students.RemoveAt(i); i--; } } } //key-value pair for names-grades Dictionary <string, string> grades = new Dictionary <string, string>(); //seed dictionary with student last, first names foreach (CourseUser student in students) { if (!grades.ContainsKey(student.UserProfile.FullName)) { grades.Add(student.UserProfile.FullName, ""); } } //get graded rubrics List <RubricEvaluation> rubricEvaluations = null; rubricEvaluations = db.RubricEvaluations.Where(re => re.Evaluator.AbstractRole.CanGrade && re.AssignmentID == assignmentID).ToList(); if (rubricEvaluations.Count > 0) //make sure there are rubrics saved { foreach (RubricEvaluation rubricEvaluation in rubricEvaluations) { string rubricStudentName = ""; //we need to go through teams to handle team assignments. this works for individuals because an individual is a team of 1 foreach (var teamMember in rubricEvaluation.Recipient.TeamMembers) { rubricStudentName = teamMember.CourseUser.UserProfile.FullName; if (rubricEvaluation.IsPublished) { //update value to match key if (grades.ContainsKey(rubricStudentName)) { grades[rubricStudentName] = RubricEvaluation.GetGradeAsDouble(rubricEvaluation.ID).ToString(); } } } } //sort the grades A-Z by last name var sortedGradesList = grades.Keys.ToList(); sortedGradesList.Sort(); //make a csv for export var csv = new StringBuilder(); foreach (var key in sortedGradesList) { //place quotes around name so the first, last format doesn't break the csv string temp = "\"" + key + "\""; var newLine = String.Format("{0},{1}{2}", temp, grades[key], Environment.NewLine); csv.Append(newLine); } const string contentType = "text/plain"; var bytes = Encoding.UTF8.GetBytes(csv.ToString()); return(File(bytes, contentType, rubricEvaluations.First().Assignment.AssignmentName + " " + DateTime.Now + " (Exported Grades).csv")); } if (Request.UrlReferrer != null) { return(Redirect(Request.UrlReferrer.ToString())); } else { return(RedirectToAction("Index", "Home", new { area = "AssignmentDetails", assignmentId = assignmentID })); } }