public static BasicResult DeleteScore(string serviceUrl, string consumerKey, string consumerSecret, string lisResultSourcedId)
        {
            var imsxEnvelope = new imsx_POXEnvelopeType
            {
                imsx_POXHeader = new imsx_POXHeaderType {Item = new imsx_RequestHeaderInfoType()},
                imsx_POXBody = new imsx_POXBodyType {Item = new deleteResultRequest()}
            };

            var imsxHeader = (imsx_RequestHeaderInfoType) imsxEnvelope.imsx_POXHeader.Item;
            imsxHeader.imsx_version = imsx_GWSVersionValueType.V10;
            imsxHeader.imsx_messageIdentifier = Guid.NewGuid().ToString();

            var imsxBody = (deleteResultRequest) imsxEnvelope.imsx_POXBody.Item;
            imsxBody.resultRecord = new ResultRecordType
            {
                sourcedGUID = new SourcedGUIDType {sourcedId = lisResultSourcedId}
            };

            try
            {
                var webRequest = CreateLtiOutcomesRequest(
                    imsxEnvelope,
                    serviceUrl,
                    consumerKey,
                    consumerSecret);
                var webResponse = webRequest.GetResponse() as HttpWebResponse;
                return ParseDeleteResultResponse(webResponse);
            }
            catch (Exception ex)
            {
                return new BasicResult(false, ex.ToString());
            }
        }
        public static BasicResult PostScore(string serviceUrl, string consumerKey, string consumerSecret, string lisResultSourcedId, double?score)
        {
            var imsxEnvelope = new imsx_POXEnvelopeType
            {
                imsx_POXHeader = new imsx_POXHeaderType {
                    Item = new imsx_RequestHeaderInfoType()
                },
                imsx_POXBody = new imsx_POXBodyType {
                    Item = new replaceResultRequest()
                }
            };

            var imsxHeader = (imsx_RequestHeaderInfoType)imsxEnvelope.imsx_POXHeader.Item;

            imsxHeader.imsx_version           = imsx_GWSVersionValueType.V10;
            imsxHeader.imsx_messageIdentifier = Guid.NewGuid().ToString();

            var imsxBody = (replaceResultRequest)imsxEnvelope.imsx_POXBody.Item;

            imsxBody.resultRecord = new ResultRecordType
            {
                sourcedGUID = new SourcedGUIDType {
                    sourcedId = lisResultSourcedId
                },
                result = new ResultType
                {
                    resultScore = new TextType
                    {
                        language   = LtiConstants.ScoreLanguage,
                        textString = score.HasValue
                            ? score.Value.ToString(new CultureInfo(LtiConstants.ScoreLanguage))
                            : 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).

            try
            {
                var webRequest = CreateLtiOutcomesRequest(
                    imsxEnvelope,
                    serviceUrl,
                    consumerKey,
                    consumerSecret);
                var webResponse = webRequest.GetResponse();
                return(ParsePostResultResponse(webResponse));
            }
            catch (Exception ex)
            {
                return(new BasicResult(false, ex.ToString()));
            }
        }
        private static HttpWebRequest CreateLtiOutcomesRequest(imsx_POXEnvelopeType imsxEnvelope, string url, string consumerKey, string consumerSecret)
        {
            var webRequest = (HttpWebRequest)WebRequest.Create(url);

            webRequest.Method      = "POST";
            webRequest.ContentType = "application/xml";

            var parameters = new NameValueCollection();

            parameters.AddParameter(OAuthConstants.ConsumerKeyParameter, consumerKey);
            parameters.AddParameter(OAuthConstants.NonceParameter, Guid.NewGuid().ToString());
            parameters.AddParameter(OAuthConstants.SignatureMethodParameter, OAuthConstants.SignatureMethodHmacSha1);
            parameters.AddParameter(OAuthConstants.VersionParameter, OAuthConstants.Version10);

            // Calculate the timestamp
            var ts        = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            var timestamp = Convert.ToInt64(ts.TotalSeconds);

            parameters.AddParameter(OAuthConstants.TimestampParameter, timestamp);

            // Calculate the body hash
            using (var ms = new MemoryStream())
                using (var sha1 = new SHA1CryptoServiceProvider())
                {
                    ImsxRequestSerializer.Serialize(ms, imsxEnvelope);
                    ms.Position = 0;
                    ms.CopyTo(webRequest.GetRequestStream());

                    var hash   = sha1.ComputeHash(ms.ToArray());
                    var hash64 = Convert.ToBase64String(hash);
                    parameters.AddParameter(OAuthConstants.BodyHashParameter, hash64);
                }

            // Calculate the signature
            var signature = OAuthUtility.GenerateSignature(webRequest.Method, webRequest.RequestUri, parameters,
                                                           consumerSecret);

            parameters.AddParameter(OAuthConstants.SignatureParameter, signature);

            // Build the Authorization header
            var authorization = new StringBuilder(OAuthConstants.AuthScheme).Append(" ");

            foreach (var key in parameters.AllKeys)
            {
                authorization.AppendFormat("{0}=\"{1}\",", key, WebUtility.UrlEncode(parameters[key]));
            }
            webRequest.Headers["Authorization"] = authorization.ToString(0, authorization.Length - 1);

            return(webRequest);
        }
        public imsx_POXEnvelopeType Post(imsx_POXEnvelopeType request)
        {
            imsx_POXEnvelopeType response;
            if (request == null)
            {
                response = CreateCustomResponse(string.Empty,
                    "Invalid request",
                    imsx_CodeMajorType.failure);
            }
            else
            {
                var requestHeader = request.imsx_POXHeader.Item as imsx_RequestHeaderInfoType;
                if (requestHeader == null)
                {
                    response = CreateCustomResponse(string.Empty,
                        "Invalid request header",
                        imsx_CodeMajorType.failure);
                }
                else
                {
                    // All requests come in the same basic body element
                    var requestBody = request.imsx_POXBody;

                    // Delete Result
                    if (requestBody.Item is deleteResultRequest)
                    {
                        response = HandleDeleteResultRequest(requestHeader, requestBody);
                    }
                    else if (requestBody.Item is readResultRequest)
                    {
                        response = HandleReadResultRequest(requestHeader, requestBody);
                    }
                    else if (requestBody.Item is replaceResultRequest)
                    {
                        response = HandleReplaceResultRequest(requestHeader, requestBody);
                    }
                    else
                    {
                        response = CreateCustomResponse(requestHeader.imsx_messageIdentifier,
                            "Request is not supported",
                            imsx_CodeMajorType.unsupported);
                    }
                }
            }
            return response;
        }
        public static LisResult ReadScore(string serviceUrl, string consumerKey, string consumerSecret, string lisResultSourcedId)
        {
            var imsxEnvelope = new imsx_POXEnvelopeType
            {
                imsx_POXHeader = new imsx_POXHeaderType {
                    Item = new imsx_RequestHeaderInfoType()
                },
                imsx_POXBody = new imsx_POXBodyType {
                    Item = new readResultRequest()
                }
            };

            var imsxHeader = (imsx_RequestHeaderInfoType)imsxEnvelope.imsx_POXHeader.Item;

            imsxHeader.imsx_version           = imsx_GWSVersionValueType.V10;
            imsxHeader.imsx_messageIdentifier = Guid.NewGuid().ToString();

            var imsxBody = (readResultRequest)imsxEnvelope.imsx_POXBody.Item;

            imsxBody.resultRecord = new ResultRecordType
            {
                sourcedGUID = new SourcedGUIDType {
                    sourcedId = lisResultSourcedId
                }
            };

            try
            {
                var webRequest = CreateLtiOutcomesRequest(
                    imsxEnvelope,
                    serviceUrl,
                    consumerKey,
                    consumerSecret);
                var webResponse = webRequest.GetResponse();
                return(ParseReadResultResponse(webResponse));
            }
            catch (Exception ex)
            {
                return(new LisResult {
                    IsValid = false, Message = ex.ToString()
                });
            }
        }
        /// <summary>
        /// Create a simple, but complete response envelope. The status is set to success.
        /// </summary>
        /// <param name="messageRefId">The request message ID.</param>
        /// <param name="description">The status description.</param>
        /// <returns>A response envelope.</returns>
        private static imsx_POXEnvelopeType CreateSuccessResponse(string messageRefId, string description)
        {
            var response = new imsx_POXEnvelopeType
            {
                imsx_POXHeader = new imsx_POXHeaderType {Item = new imsx_ResponseHeaderInfoType()}
            };

            var item = (imsx_ResponseHeaderInfoType) response.imsx_POXHeader.Item;
            item.imsx_version = imsx_GWSVersionValueType.V10;
            item.imsx_messageIdentifier = Guid.NewGuid().ToString();
            item.imsx_statusInfo = new imsx_StatusInfoType();

            var status = item.imsx_statusInfo;
            status.imsx_codeMajor = imsx_CodeMajorType.success;
            status.imsx_severity = imsx_SeverityType.status;
            status.imsx_description = description;
            status.imsx_messageRefIdentifier = messageRefId;

            response.imsx_POXBody = new imsx_POXBodyType();
            return response;
        }
        private static HttpWebRequest CreateLtiOutcomesRequest(imsx_POXEnvelopeType imsxEnvelope, string url, string consumerKey, string consumerSecret)
        {
            var webRequest = (HttpWebRequest) WebRequest.Create(url);
            webRequest.Method = "POST";
            webRequest.ContentType = "application/xml";

            var parameters = new NameValueCollection();
            parameters.AddParameter(OAuthConstants.ConsumerKeyParameter, consumerKey);
            parameters.AddParameter(OAuthConstants.NonceParameter, Guid.NewGuid().ToString());
            parameters.AddParameter(OAuthConstants.SignatureMethodParameter, OAuthConstants.SignatureMethodHmacSha1);
            parameters.AddParameter(OAuthConstants.VersionParameter, OAuthConstants.Version10);

            // Calculate the timestamp
            var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            var timestamp = Convert.ToInt64(ts.TotalSeconds);
            parameters.AddParameter(OAuthConstants.TimestampParameter, timestamp);

            // Calculate the body hash
            using (var ms = new MemoryStream())
            using (var sha1 = new SHA1CryptoServiceProvider())
            {
                ImsxRequestSerializer.Serialize(ms, imsxEnvelope);
                ms.Position = 0;
                ms.CopyTo(webRequest.GetRequestStream());

                var hash = sha1.ComputeHash(ms.ToArray());
                var hash64 = Convert.ToBase64String(hash);
                parameters.AddParameter(OAuthConstants.BodyHashParameter, hash64);
            }

            // Calculate the signature
            var signature = OAuthUtility.GenerateSignature(webRequest.Method, webRequest.RequestUri, parameters,
                consumerSecret);
            parameters.AddParameter(OAuthConstants.SignatureParameter, signature);

            // Build the Authorization header
            var authorization = new StringBuilder(OAuthConstants.AuthScheme).Append(" ");
            foreach (var key in parameters.AllKeys)
            {
                authorization.AppendFormat("{0}=\"{1}\",", key, WebUtility.UrlEncode(parameters[key]));
            }
            webRequest.Headers["Authorization"] = authorization.ToString(0, authorization.Length - 1);

            return webRequest;
        }
        public static BasicResult PostScore(string serviceUrl, string consumerKey, string consumerSecret, string lisResultSourcedId, double? score)
        {
            var imsxEnvelope = new imsx_POXEnvelopeType
            {
                imsx_POXHeader = new imsx_POXHeaderType {Item = new imsx_RequestHeaderInfoType()},
                imsx_POXBody = new imsx_POXBodyType {Item = new replaceResultRequest()}
            };

            var imsxHeader = (imsx_RequestHeaderInfoType) imsxEnvelope.imsx_POXHeader.Item;
            imsxHeader.imsx_version = imsx_GWSVersionValueType.V10;
            imsxHeader.imsx_messageIdentifier = Guid.NewGuid().ToString();

            var imsxBody = (replaceResultRequest) imsxEnvelope.imsx_POXBody.Item;
            imsxBody.resultRecord = new ResultRecordType
            {
                sourcedGUID = new SourcedGUIDType {sourcedId = lisResultSourcedId},
                result = new ResultType
                {
                    resultScore = new TextType
                    {
                        language = LtiConstants.ScoreLanguage,
                        textString = score.HasValue
                            ? score.Value.ToString(CultureInfo.CreateSpecificCulture(LtiConstants.ScoreLanguage))
                            : 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).

            try
            {
                var webRequest = CreateLtiOutcomesRequest(
                    imsxEnvelope,
                    serviceUrl,
                    consumerKey,
                    consumerSecret);
                var webResponse = webRequest.GetResponse() as HttpWebResponse;
                return ParsePostResultResponse(webResponse);
            }
            catch (Exception ex)
            {
                return new BasicResult(false, ex.ToString());
            }
        }