public PostResultContext(string contextId, string lineItemId, LisResult result)
 {
     ContextId  = contextId;
     LineItemId = lineItemId;
     Result     = result;
     StatusCode = HttpStatusCode.OK;
 }
 /// <summary>
 /// Delete the score from the consumer database.
 /// </summary>
 /// <param name="lisResultSourcedId">The SourcedId of the score to delete.</param>
 /// <returns>True if the score is deleted.</returns>
 protected override bool DeleteResult(string lisResultSourcedId)
 {
     if (LisResultSourcedIdIsValid(lisResultSourcedId))
     {
         _lisResult = null;
         return(true);
     }
     return(false);
 }
Beispiel #3
0
        /// <summary>
        /// Create a new Score based on the Result that was sent.
        /// </summary>
        /// <param name="result">The result record that was sent in the request.</param>
        /// <returns>The Score based on the result.</returns>
        private static Score CreateScore(LisResult result)
        {
            var sourcedId = JsonConvert.DeserializeObject <LisResultSourcedId>(result.SourcedId);

            return(new Score
            {
                AssignmentId = sourcedId.AssignmentId,
                UserId = sourcedId.UserId
            });
        }
 /// <summary>
 /// Delete the score from the consumer database.
 /// </summary>
 /// <param name="lisResultSourcedId">The SourcedId of the score to delete.</param>
 /// <returns>True if the score is deleted.</returns>
 protected override bool DeleteResult(string lisResultSourcedId)
 {
     // Only valid SourcedId values are "1", "2", and "3" (see Lti1Controller)
     if (lisResultSourcedId.Equals("1") || lisResultSourcedId.Equals("2") || lisResultSourcedId.Equals("3"))
     {
         _lisResult = null;
         return(true);
     }
     return(false);
 }
 /// <summary>
 /// Store the score in the consumer database.
 /// </summary>
 /// <param name="result">The LisResult to store.</param>
 /// <returns>True if the score is saved.</returns>
 protected override bool ReplaceResult(LisResult result)
 {
     if (_lisResult == null)
     {
         _lisResult = new LisResult();
     }
     _lisResult.IsValid   = true;
     _lisResult.Score     = result.Score;
     _lisResult.SourcedId = result.SourcedId;
     return(true);
 }
 /// <summary>
 /// Store the score in the consumer database.
 /// </summary>
 /// <param name="result">The LisResult to store.</param>
 /// <returns>True if the score is saved.</returns>
 protected override bool ReplaceResult(LisResult result)
 {
     // Only valid SourcedId values are "1", "2", and "3" (see Lti1Controller)
     if (result.SourcedId.Equals("1") || result.SourcedId.Equals("2") || result.SourcedId.Equals("3"))
     {
         if (_lisResult == null)
         {
             _lisResult = new LisResult();
         }
         _lisResult.IsValid   = true;
         _lisResult.Score     = result.Score;
         _lisResult.SourcedId = result.SourcedId;
         return(true);
     }
     return(false);
 }
Beispiel #7
0
        /// <summary>
        /// Fill the Result with corresponding Score data.
        /// </summary>
        /// <param name="lisResultSourcedId">The sourcedId of the LisResult to read.</param>
        /// <returns>True if the Score was found and the Result is valid.</returns>
        protected override LisResult ReadResult(string lisResultSourcedId)
        {
            var score  = GetScore(lisResultSourcedId);
            var result = new LisResult();

            if (score.IsValid)
            {
                result.IsValid   = true;
                result.Score     = score.Score == null ? default(double?) : score.Score.DoubleValue;
                result.SourcedId = lisResultSourcedId;
            }
            else
            {
                result.IsValid = false;
            }
            return(result);
        }
Beispiel #8
0
        /// <summary>
        /// Create or update a Score with the LTI result.
        /// </summary>
        /// <param name="result">The LTI result.</param>
        /// <returns>True if the Score was created or updated.</returns>
        protected override bool ReplaceResult(LisResult result)
        {
            var score = GetScore(result.SourcedId);

            if (score.IsValid)
            {
                if (score.Score == null)
                {
                    score.Score = CreateScore(result);
                    ConsumerContext.Scores.Add(score.Score);
                }
                if (result.Score.HasValue)
                {
                    score.Score.DoubleValue = result.Score.Value;
                }
                ConsumerContext.SaveChanges();
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// Convert the ResultRecordType into the Result type.
        /// </summary>
        /// <param name="resultRecord">The ResultRecordType which
        /// specifies the assignment and score.</param>
        /// <returns>The corresponding Result</returns>
        private static LisResult GetResult(ResultRecordType resultRecord)
        {
            var result = new LisResult {
                SourcedId = resultRecord.sourcedGUID.sourcedId
            };

            if (resultRecord.result != null)
            {
                // The LTI 1.1 specification states in 6.1.1. that the score in replaceResult should
                // always be formatted using “en” formatting
                // (http://www.imsglobal.org/LTI/v1p1p1/ltiIMGv1p1p1.html#_Toc330273034).
                const NumberStyles style = NumberStyles.Number | NumberStyles.AllowDecimalPoint;
                var    culture           = CultureInfo.CreateSpecificCulture(LtiConstants.ScoreLanguage);
                double value;
                if (double.TryParse(resultRecord.result.resultScore.textString, style, culture, out value))
                {
                    if (value >= 0 && value <= 1)
                    {
                        result.Score = value;
                    }
                }
            }
            return(result);
        }
        public async Task <ActionResult> Outcomes2(Outcomes2Model model, string submit)
        {
            switch (submit)
            {
            case "Delete LineItem (Delete)":
                var deleteLineItemResponse = await OutcomesClient.DeleteLineItem(
                    model.LineItemServiceUrl,
                    model.ConsumerKey,
                    model.ConsumerSecret);

                model.HttpRequest  = deleteLineItemResponse.HttpRequest;
                model.HttpResponse = deleteLineItemResponse.HttpResponse;
                switch (deleteLineItemResponse.StatusCode)
                {
                case HttpStatusCode.OK:
                    model.LineItem = null;
                    ModelState.Clear();
                    ViewBag.Message = "200 LineItem deleted";
                    break;

                case HttpStatusCode.Unauthorized:
                    ViewBag.Message = "401 Not authorized";
                    break;

                case HttpStatusCode.NotFound:
                    ViewBag.Message = "404 Not found";
                    break;

                case HttpStatusCode.InternalServerError:
                    ViewBag.Message = "500 Internal server error";
                    break;

                default:
                    ViewBag.Message = Convert.ToInt32(deleteLineItemResponse.StatusCode) + " " + deleteLineItemResponse.StatusCode;
                    break;
                }
                break;

            case "Get LineItem (Read)":
                var getLineItemResponse = await OutcomesClient.GetLineItem(
                    model.LineItemServiceUrl,
                    model.ConsumerKey,
                    model.ConsumerSecret);

                model.HttpRequest  = getLineItemResponse.HttpRequest;
                model.HttpResponse = getLineItemResponse.HttpResponse;
                switch (getLineItemResponse.StatusCode)
                {
                case HttpStatusCode.OK:
                    model.LineItem = getLineItemResponse.Outcome;
                    ModelState.Clear();
                    ViewBag.Message = "200 LineItem received";
                    break;

                case HttpStatusCode.Unauthorized:
                    ViewBag.Message = "401 Not authorized";
                    break;

                case HttpStatusCode.NotFound:
                    ViewBag.Message = "404 Not found";
                    break;

                case HttpStatusCode.InternalServerError:
                    ViewBag.Message = "500 Internal server error";
                    break;

                default:
                    ViewBag.Message = Convert.ToInt32(getLineItemResponse.StatusCode) + " " + getLineItemResponse.StatusCode;
                    break;
                }
                break;

            case "Get LineItemResults (Read)":
                var getLineItemResultsResponse = await OutcomesClient.GetLineItemWithResults(
                    model.LineItemServiceUrl,
                    model.ConsumerKey,
                    model.ConsumerSecret);

                model.HttpRequest  = getLineItemResultsResponse.HttpRequest;
                model.HttpResponse = getLineItemResultsResponse.HttpResponse;
                switch (getLineItemResultsResponse.StatusCode)
                {
                case HttpStatusCode.OK:
                    model.LineItem = getLineItemResultsResponse.Outcome;
                    ModelState.Clear();
                    ViewBag.Message = "200 LineItem received";
                    break;

                case HttpStatusCode.Unauthorized:
                    ViewBag.Message = "401 Not authorized";
                    break;

                case HttpStatusCode.NotFound:
                    ViewBag.Message = "404 Not found";
                    break;

                case HttpStatusCode.InternalServerError:
                    ViewBag.Message = "500 Internal server error";
                    break;

                default:
                    ViewBag.Message = Convert.ToInt32(getLineItemResultsResponse.StatusCode) + " " + getLineItemResultsResponse.StatusCode;
                    break;
                }
                break;

            case "Get LineItems (Read)":
                var getLineItemsResponse = await OutcomesClient.GetLineItems(
                    model.LineItemsServiceUrl,
                    model.ConsumerKey,
                    model.ConsumerSecret,
                    activityId : model.LineItem.AssignedActivity.ActivityId);

                model.HttpRequest  = getLineItemsResponse.HttpRequest;
                model.HttpResponse = getLineItemsResponse.HttpResponse;
                switch (getLineItemsResponse.StatusCode)
                {
                case HttpStatusCode.OK:
                    ViewBag.Message = "200 LineItems received";
                    break;

                case HttpStatusCode.Unauthorized:
                    ViewBag.Message = "401 Not authorized";
                    break;

                case HttpStatusCode.NotFound:
                    ViewBag.Message = "404 Not found";
                    break;

                case HttpStatusCode.InternalServerError:
                    ViewBag.Message = "500 Internal server error";
                    break;

                default:
                    ViewBag.Message = Convert.ToInt32(getLineItemsResponse.StatusCode) + " " + getLineItemsResponse.StatusCode;
                    break;
                }
                break;

            case "Post LineItem (Create)":
                var postLineItem = new LineItem
                {
                    ReportingMethod = "totalScore",
                    LineItemOf      = new Context {
                        ContextId = model.ContextId
                    },
                    AssignedActivity = new Activity {
                        ActivityId = model.LineItem.AssignedActivity.ActivityId
                    },
                    ScoreContraints = new NumericLimits {
                        NormalMaximum = 100, ExtraCreditMaximum = 10, TotalMaximum = 110
                    }
                };
                var postLineItemResponse = await OutcomesClient.PostLineItem(
                    postLineItem,
                    model.LineItemsServiceUrl,
                    model.ConsumerKey,
                    model.ConsumerSecret);

                model.HttpRequest  = postLineItemResponse.HttpRequest;
                model.HttpResponse = postLineItemResponse.HttpResponse;
                switch (postLineItemResponse.StatusCode)
                {
                case HttpStatusCode.Created:
                    model.LineItem = postLineItemResponse.Outcome;
                    ModelState.Clear();
                    ViewBag.Message = "201 LineItem added";
                    break;

                case HttpStatusCode.BadRequest:
                    ViewBag.Message = "400 Bad Request";
                    break;

                case HttpStatusCode.Unauthorized:
                    ViewBag.Message = "401 Not authorized";
                    break;

                case HttpStatusCode.InternalServerError:
                    ViewBag.Message = "500 Internal server error";
                    break;

                default:
                    ViewBag.Message = Convert.ToInt32(postLineItemResponse.StatusCode) + " " + postLineItemResponse.StatusCode;
                    break;
                }
                break;

            case "Put LineItem (Update)":
                var putLineItem = new LineItem
                {
                    Id = model.LineItem.Id,
                    ReportingMethod = "totalScore",
                    LineItemOf      = new Context {
                        ContextId = model.ContextId
                    },
                    AssignedActivity = new Activity {
                        ActivityId = model.LineItem.AssignedActivity.ActivityId
                    },
                    ScoreContraints = new NumericLimits {
                        NormalMaximum = 100, ExtraCreditMaximum = 10, TotalMaximum = 110
                    },
                    Results = model.LineItem.Results
                };
                var putLineItemResponse = await OutcomesClient.PutLineItem(
                    putLineItem,
                    model.LineItemsServiceUrl,
                    model.ConsumerKey,
                    model.ConsumerSecret);

                model.HttpRequest  = putLineItemResponse.HttpRequest;
                model.HttpResponse = putLineItemResponse.HttpResponse;
                switch (putLineItemResponse.StatusCode)
                {
                case HttpStatusCode.OK:
                    ViewBag.Message = "200 LineItem updated";
                    break;

                case HttpStatusCode.Unauthorized:
                    ViewBag.Message = "401 Not authorized";
                    break;

                case HttpStatusCode.NotFound:
                    ViewBag.Message = "404 Not found";
                    break;

                case HttpStatusCode.InternalServerError:
                    ViewBag.Message = "500 Internal server error";
                    break;

                default:
                    ViewBag.Message = Convert.ToInt32(putLineItemResponse.StatusCode) + " " + putLineItemResponse.StatusCode;
                    break;
                }
                break;

            case "Delete Result (Delete)":
                var deleteResultResponse = await OutcomesClient.DeleteResult(
                    model.ResultServiceUrl,
                    model.ConsumerKey,
                    model.ConsumerSecret);

                model.HttpRequest  = deleteResultResponse.HttpRequest;
                model.HttpResponse = deleteResultResponse.HttpResponse;
                switch (deleteResultResponse.StatusCode)
                {
                case HttpStatusCode.OK:
                    model.LineItem = null;
                    ModelState.Clear();
                    ViewBag.Message = "200 Result deleted";
                    break;

                case HttpStatusCode.Unauthorized:
                    ViewBag.Message = "401 Not authorized";
                    break;

                case HttpStatusCode.NotFound:
                    ViewBag.Message = "404 Not found";
                    break;

                case HttpStatusCode.InternalServerError:
                    ViewBag.Message = "500 Internal server error";
                    break;

                default:
                    ViewBag.Message = Convert.ToInt32(deleteResultResponse.StatusCode) + " " + deleteResultResponse.StatusCode;
                    break;
                }
                break;

            case "Get Result (Read)":
                var getResultResponse = await OutcomesClient.GetResult(
                    model.ResultServiceUrl,
                    model.ConsumerKey,
                    model.ConsumerSecret);

                model.HttpRequest  = getResultResponse.HttpRequest;
                model.HttpResponse = getResultResponse.HttpResponse;
                switch (getResultResponse.StatusCode)
                {
                case HttpStatusCode.OK:
                    model.Result = getResultResponse.Outcome;
                    ModelState.Clear();
                    ViewBag.Message = "200 LineItem received";
                    break;

                case HttpStatusCode.Unauthorized:
                    ViewBag.Message = "401 Not authorized";
                    break;

                case HttpStatusCode.NotFound:
                    ViewBag.Message = "404 Not found";
                    break;

                case HttpStatusCode.InternalServerError:
                    ViewBag.Message = "500 Internal server error";
                    break;

                default:
                    ViewBag.Message = Convert.ToInt32(getResultResponse.StatusCode) + " " + getResultResponse.StatusCode;
                    break;
                }
                break;

            case "Get Results (Read)":
                var getResultsResponse = await OutcomesClient.GetResults(
                    model.ResultsServiceUrl,
                    model.ConsumerKey,
                    model.ConsumerSecret);

                model.HttpRequest  = getResultsResponse.HttpRequest;
                model.HttpResponse = getResultsResponse.HttpResponse;
                switch (getResultsResponse.StatusCode)
                {
                case HttpStatusCode.OK:
                    ViewBag.Message = "200 Results received";
                    break;

                case HttpStatusCode.Unauthorized:
                    ViewBag.Message = "401 Not authorized";
                    break;

                case HttpStatusCode.NotFound:
                    ViewBag.Message = "404 Not found";
                    break;

                case HttpStatusCode.InternalServerError:
                    ViewBag.Message = "500 Internal server error";
                    break;

                default:
                    ViewBag.Message = Convert.ToInt32(getResultsResponse.StatusCode) + " " + getResultsResponse.StatusCode;
                    break;
                }
                break;

            case "Post Result (Create)":
                var postResult =
                    new LisResult
                {
                    Comment     = "Good job!",
                    ResultAgent = new LisPerson {
                        UserId = "12345"
                    },
                    ResultOf               = new Uri(model.LineItemServiceUrl),
                    ResultScore            = "0.75",
                    ResultScoreConstraints = new NumericLimits {
                        TotalMaximum = 1
                    },
                    ResultStatus = ResultStatus.Completed,
                    TotalScore   = (decimal?)0.75
                };
                var postResultResponse = await OutcomesClient.PostResult(
                    postResult,
                    model.ResultServiceUrl,
                    model.ConsumerKey,
                    model.ConsumerSecret);

                model.HttpRequest  = postResultResponse.HttpRequest;
                model.HttpResponse = postResultResponse.HttpResponse;
                switch (postResultResponse.StatusCode)
                {
                case HttpStatusCode.Created:
                    //model.LineItem = postResult.Outcome;
                    ModelState.Clear();
                    ViewBag.Message = "201 Result added";
                    break;

                case HttpStatusCode.BadRequest:
                    ViewBag.Message = "400 Bad Request";
                    break;

                case HttpStatusCode.Unauthorized:
                    ViewBag.Message = "401 Not authorized";
                    break;

                case HttpStatusCode.InternalServerError:
                    ViewBag.Message = "500 Internal server error";
                    break;

                default:
                    ViewBag.Message = Convert.ToInt32(postResultResponse.StatusCode) + " " + postResultResponse.StatusCode;
                    break;
                }
                break;

            case "Put Result (Update)":
                var putResult =
                    new LisResult
                {
                    Comment     = "Good job!",
                    ResultAgent = new LisPerson {
                        UserId = "12345"
                    },
                    ResultOf               = new Uri(model.LineItemServiceUrl),
                    ResultScore            = "0.75",
                    ResultScoreConstraints = new NumericLimits {
                        TotalMaximum = 1
                    },
                    ResultStatus = ResultStatus.Final,         // Change the status to Final
                    TotalScore   = (decimal?)0.75
                };
                var putResultResponse = await OutcomesClient.PutResult(
                    putResult,
                    model.ResultServiceUrl,
                    model.ConsumerKey,
                    model.ConsumerSecret);

                model.HttpRequest  = putResultResponse.HttpRequest;
                model.HttpResponse = putResultResponse.HttpResponse;
                switch (putResultResponse.StatusCode)
                {
                case HttpStatusCode.OK:
                    ViewBag.Message = "200 Result updated";
                    break;

                case HttpStatusCode.Unauthorized:
                    ViewBag.Message = "401 Not authorized";
                    break;

                case HttpStatusCode.NotFound:
                    ViewBag.Message = "404 Not found";
                    break;

                case HttpStatusCode.InternalServerError:
                    ViewBag.Message = "500 Internal server error";
                    break;

                default:
                    ViewBag.Message = Convert.ToInt32(putResultResponse.StatusCode) + " " + putResultResponse.StatusCode;
                    break;
                }
                break;
            }
            return(View(model));
        }
Beispiel #11
0
        public async Task <HttpResponseMessage> Put(string contextId, string lineItemId, string id, LisResult result)
        {
            try
            {
                var context = new PutResultContext(contextId, lineItemId, id, result);

                await OnPutResult(context);

                return(Request.CreateResponse(context.StatusCode));
            }
            catch (Exception ex)
            {
                return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex));
            }
        }
Beispiel #12
0
        public async Task <HttpResponseMessage> Post(string contextId, string lineItemId, LisResult result)
        {
            try
            {
                var context = new PostResultContext(contextId, lineItemId, result);

                await OnPostResult(context);

                return(context.StatusCode == HttpStatusCode.Created
                    ? Request.CreateResponse(context.StatusCode, context.Result, new ResultFormatter())
                    : Request.CreateResponse(context.StatusCode));
            }
            catch (Exception ex)
            {
                return(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex));
            }
        }
 /// <summary>
 /// Save or update the result (grade, score, outcome) in the consumer.
 /// </summary>
 /// <param name="result">The result to save or update.</param>
 /// <returns>True if the result was saved or updated.</returns>
 protected abstract bool ReplaceResult(LisResult result);
        public LineItemsController()
        {
            OnDeleteLineItem = context =>
            {
                var lineItemUri = RoutingHelper.GetLineItemsUri(new HttpContextWrapper(HttpContext.Current), ContextId, context.Id);

                if (LineItem == null || !LineItem.Id.Equals(lineItemUri))
                {
                    context.StatusCode = HttpStatusCode.NotFound;
                }
                else
                {
                    LineItem           = null;
                    Result             = null;
                    context.StatusCode = HttpStatusCode.OK;
                }
                return(Task.FromResult <object>(null));
            };

            OnGetLineItem = context =>
            {
                var lineItemUri = RoutingHelper.GetLineItemsUri(new HttpContextWrapper(HttpContext.Current), context.ContextId, context.Id);

                if (LineItem == null || !LineItem.Id.Equals(lineItemUri))
                {
                    context.StatusCode = HttpStatusCode.NotFound;
                }
                else
                {
                    context.LineItem   = LineItem;
                    context.StatusCode = HttpStatusCode.OK;
                }
                return(Task.FromResult <object>(null));
            };

            OnGetLineItemWithResults = context =>
            {
                OnGetLineItem(context);
                if (context.LineItem != null && Result != null)
                {
                    context.LineItem.Result = Result == null ? new LisResult[] {} : new[] { Result };
                }
                return(Task.FromResult <object>(null));
            };

            OnGetLineItems = context =>
            {
                context.LineItemContainerPage = new LineItemContainerPage
                {
                    ExternalContextId = LtiConstants.LineItemContainerContextId,
                    Id = RoutingHelper.GetLineItemsUri(new HttpContextWrapper(HttpContext.Current), context.ContextId),
                    LineItemContainer = new LineItemContainer
                    {
                        MembershipSubject = new LineItemMembershipSubject
                        {
                            ContextId = context.ContextId,
                            LineItems = new LineItem[] { }
                        }
                    }
                };

                if (LineItem != null &&
                    (string.IsNullOrEmpty(context.ActivityId) ||
                     context.ActivityId.Equals(LineItem.AssignedActivity.ActivityId)))
                {
                    context.LineItemContainerPage.LineItemContainer.MembershipSubject.LineItems = new[] { LineItem };
                }
                context.StatusCode = HttpStatusCode.OK;
                return(Task.FromResult <object>(null));
            };

            // Create a LineItem
            OnPostLineItem = context =>
            {
                if (LineItem != null)
                {
                    context.StatusCode = HttpStatusCode.BadRequest;
                    return(Task.FromResult <object>(null));
                }

                // Normally LineItem.Id would be calculated based on an id assigned by the database
                context.LineItem.Id      = RoutingHelper.GetLineItemsUri(new HttpContextWrapper(HttpContext.Current), context.ContextId, LineItemId);
                context.LineItem.Results = RoutingHelper.GetResultsUri(new HttpContextWrapper(HttpContext.Current), context.ContextId, LineItemId);
                LineItem           = context.LineItem;
                context.StatusCode = HttpStatusCode.Created;
                return(Task.FromResult <object>(null));
            };

            // Update LineItem (but not results)
            OnPutLineItem = context =>
            {
                if (context.LineItem == null || LineItem == null || !LineItem.Id.Equals(context.LineItem.Id))
                {
                    context.StatusCode = HttpStatusCode.NotFound;
                }
                else
                {
                    context.LineItem.Result = LineItem.Result;
                    LineItem           = context.LineItem;
                    context.StatusCode = HttpStatusCode.OK;
                }
                return(Task.FromResult <object>(null));
            };

            // Update LineItem and Result
            OnPutLineItemWithResults = context =>
            {
                if (context.LineItem == null || LineItem == null || !LineItem.Id.Equals(context.LineItem.Id))
                {
                    context.StatusCode = HttpStatusCode.NotFound;
                }
                else
                {
                    LineItem = context.LineItem;
                    if (context.LineItem.Result != null && context.LineItem.Result.Length > 0)
                    {
                        Result = context.LineItem.Result[0];
                    }
                    context.StatusCode = HttpStatusCode.OK;
                }
                return(Task.FromResult <object>(null));
            };
        }
 /// <summary>
 /// Delete the score from the consumer database.
 /// </summary>
 /// <param name="lisResultSourcedId">The SourcedId of the score to delete.</param>
 /// <returns>True if the score is deleted.</returns>
 protected override bool DeleteResult(string lisResultSourcedId)
 {
     _lisResult = null;
     return(true);
 }