protected void Page_Load(object sender, EventArgs e)
    {
        // set <currentUser> to information about the current user, and add the current user's list
        // of training to the TrainingGrid table; for best performance, both these requests are
        // done in a single call to the database
        LearningStoreJob job = LStore.CreateJob();

        RequestCurrentUserInfo(job);
        RequestMyTraining(job, null);
        ReadOnlyCollection <object> results = job.Execute();
        LStoreUserInfo currentUser          = GetCurrentUserInfoResults((DataTable)results[0]);

        GetMyTrainingResultsToHtml((DataTable)results[1], TrainingGrid);

        // update the title
        MyUserName.Text = Server.HtmlEncode(currentUser.Name);

        // if there is no training (i.e. if TrainingGrid contains only the header row), initially
        // hide TrainingGrid and show a message instructing the user to upload content
        if (TrainingGrid.Rows.Count == 1)
        {
            TrainingPanel.Attributes.Add("style", "display: none");
        }
        else
        {
            NoTrainingMessage.Attributes.Add("style", "display: none");
        }

        // since there is no initial selection, intially disable the "Delete Packages" link
        DeletePackagesLink.Attributes.Add("disabled", "true");

        // set the version number
        VersionNumber.Text = System.Text.RegularExpressions.Regex.Match(
            typeof(LearningStore).Assembly.FullName, @"\bVersion=(\d+\.\d+.\d+)\.").Groups[1].Value;
    }
    protected void CreateAttemptButton_Click(object sender, EventArgs e)
    {
        // the hidden "Create Attempt" button was auto-clicked by script on page load...

        // prevent script from clicking "Create Attempt" again
        AutoPostScript.Visible = false;

        // hide the "please wait" panel
        PleaseWait.Visible = false;

        // the OrganizationId hidden form element contains the ID of the organization to attempt --
        // try to create a new attempt based on that ID; an organization is a root-level activity,
        // so OrganizationId is actually an ActivityPackageItemIdentifier
        try
        {
            // set <currentUser> to information about the current user; we
            // need the current user's UserItemIdentifier
            LStoreUserInfo currentUser = GetCurrentUserInfo();

            // set <organizationId> from the OrganizationId hidden form element as described above
            ActivityPackageItemIdentifier organizationId = new ActivityPackageItemIdentifier(
                Convert.ToInt64(OrganizationId.Value, CultureInfo.InvariantCulture));

            // create an attempt on <organizationId>
            StoredLearningSession session = StoredLearningSession.CreateAttempt(PStore,
                                                                                currentUser.Id, organizationId, LoggingOptions.LogAll);

            // the operation was successful, and there are no messages to display to the user, so
            // update the AttemptId hidden form element with the ID of the newly-created attempt,
            // update the parent page, and close the dialog
            AttemptId.Value = Convert.ToString(session.AttemptId.GetKey(), CultureInfo.InvariantCulture);
            UpdateParentPageScript.Visible = true;
            CloseDialogScript.Visible      = true;
        }
        catch (Exception ex)
        {
            // an unexpected error occurred -- display a generic message that
            // doesn't include the exception message (since that message may
            // include sensitive information), and write the exception message
            // to the event log
            ErrorIntro.Visible   = true;
            ErrorMessage.Visible = true;
            ErrorMessage.Controls.Add(new System.Web.UI.LiteralControl(
                                          Server.HtmlEncode("A serious error occurred.  Please contact your system administrator.  More information has been written to the server event log.")));
            LogEvent(System.Diagnostics.EventLogEntryType.Error,
                     "An exception occurred while creating an attempt:\n\n{0}\n\n", ex.ToString());
            Buttons.Visible = true;
        }
    }
    protected void UploadPackageButton_OnClick(object sender, EventArgs e)
    {
        // the user clicked "Upload"...

        // do nothing if the user didn't select a file to upload
        if (!UploadedPackageFile.HasFile)
        {
            return;
        }

        // hide the upload panel and show the message panel; the message panel will hold
        // information about the success or failure of the package upload operation
        UploadPanel.Visible  = false;
        MessagePanel.Visible = true;

        // attempt to import the uploaded file into PackageStore
        try
        {
            // set <currentUser> to information about the current user; we need the current user's
            // UserItemIdentifier
            LStoreUserInfo currentUser = GetCurrentUserInfo();

            // import the package file; set packageId to the ID of the uploaded
            // package; set importLog to a collection of warnings (if any)
            // about the import process
            PackageItemIdentifier packageId;
            ValidationResults     importLog;
            using (PackageReader packageReader = PackageReader.Create(UploadedPackageFile.FileContent))
            {
                // Add package, asking to fix anything that can be fixed.
                AddPackageResult result = PStore.AddPackage(packageReader, new PackageEnforcement(false, false, false));
                packageId = result.PackageId;
                importLog = result.Log;
            }

            // fill in the application-specific columns of the PackageItem table
            LearningStoreJob            job        = LStore.CreateJob();
            Dictionary <string, object> properties = new Dictionary <string, object>();
            properties[Schema.PackageItem.Owner]          = currentUser.Id;
            properties[Schema.PackageItem.FileName]       = UploadedPackageFile.FileName;
            properties[Schema.PackageItem.UploadDateTime] = DateTime.Now;
            job.UpdateItem(packageId, properties);
            job.Execute();

            // retrieve information about the package
            job = LStore.CreateJob();
            RequestMyTraining(job, packageId);
            GetMyTrainingResultsToHtml(job.Execute <DataTable>(), TrainingGrid);

            // when the page loads in the browser, copy information about the from the TrainingGrid
            // hidden table to the main page using client-side script
            UpdateParentPageScript.Visible = true;

            // provide user feedback
            if (importLog.HasWarnings)
            {
                // display warnings
                WarningIntro.Visible    = true;
                WarningMessages.Visible = true;
                foreach (ValidationResult result in importLog.Results)
                {
                    ScrollingMessagesList.Items.Add(new ListItem(result.Message));
                }
            }
            else
            {
                // the operation was successful, and there are no messages to display to the user,
                // so close the dialog
                CloseDialogScript.Visible = true;
            }
        }
        catch (PackageImportException ex)
        {
            // a package import failure occurred -- display the error message
            ErrorIntro.Visible   = true;
            ErrorMessage.Visible = true;

            foreach (ValidationResult result in ex.Log.Results)
            {
                ErrorMessageScrollingList.Items.Add(new ListItem(result.Message));
            }

            if (ex.InnerException != null)
            {
                ErrorMessageScrollingList.Items.Add(new ListItem(
                                                        Server.HtmlEncode(ex.InnerException.Message)));
            }
        }
        catch (Exception ex)
        {
            // an unexpected error occurred -- display a generic message that doesn't include the
            // exception message (since that message may include sensitive information), and write
            // the exception message to the event log
            ErrorIntro.Visible   = true;
            ErrorMessage.Visible = true;
            ErrorMessage.Controls.Add(new System.Web.UI.LiteralControl(
                                          Server.HtmlEncode("A serious error occurred.  Please contact your system administrator.  More information has been written to the server event log.")));
            LogEvent(System.Diagnostics.EventLogEntryType.Error,
                     "An exception occurred while uploading a package:\n\n{0}\n\n", ex.ToString());
        }
    }