LtiLibrary 1.4 on NuGet

LtiLibrary 1.4.2 is now available on NuGet and there is a sample to go with it. The big changes from version 1.3.3 are support for LTI 1.2 Public Draft and LTI Content-Item Message 1.0 Public Draft. You can get both draft specifications from IMS. LtiLibrary release notes are on CodePlex along with all the source code.

The Consumer and Provider websites have been updated to use LtiLibrary 1.4 (and to use the new Microsoft Identity framework so your old username is probably gone). To play around with the Content-Item Message, try this:

  1. Login to Consumer. Make sure you are a teacher.
  2. Create a Course.
  3. In the Course Details view, open the Assignments section and click on Sample Provider Library to launch a content selector running on Provider.
  4. Decide which tool you want to insert into your course, and click on Assign. This will insert the tool into your course.

You may notice that Content-Item Message 1.0 is designed as a browser-to-browser message. When the Content-Item Message handler sends the selection back to the Tool Consumer, the browser is redirected to the Tool Consumer and the Content-Item Message handler state is lost. This makes it different than the server-to-server messaging of LTI Outcomes and Tool Consumer Profile and I’m not sure how I feel about that.

The use cases imagine involve selecting multiple things and sending them back to the Tool Consumer. The process of selecting multiple things might take several complicated steps (such as a search with several filters applied). But as soon as the Content-Item Message handler sends the first selection back to the Tool Consumer, the search results would be lost. This can be overcome by making the Content-Item Message handler capable of assembling several items before sending them back to the Tool Consumer, but it seems like it would be easier to let the Content-Item Message handler send intermediate results back to the Tool Consumer via server-to-server messages with the final “I’m Done” message browser-to-browser.

What do you think?

Provider is also using the new MVC template based on Bootstrap. Consumer is still using the old template based on jQuery UI. After going through the conversion, I found it takes about the same amount of effort to create new views on either. But I suspect Provider will run on mobile devices with less fiddling.

As I mentioned above, both Provider and Consumer are using the new Microsoft Identify framework. Converting from Simple Membership to Identity was pretty straightforward, though tedious. I was surprised how often I was using identity features that are no longer supported or supported in a different way. The only significant change was in the LtiAuthorizeAttribute.OnAuthorization override which no longer adds the signed in user to the authorization cookie. Instead I simply redirect to the destination page and let the Identify framework do the dirty work. This results in one more browser request, but otherwise is quite transparent. [This is also why the browser back button will generate a “you’ve already used that Nonce” message after an LTI launch. I’ll work on that later.]

Posted in Uncategorized | Tagged , , , , | 2 Comments

LTI Talks Back with Content Item Message

Here’s a common use case…a teacher finds something online she wants all her kids to use in the classroom. So she copies the URL and pastes it into her learning system (LMS, Google Docs, whatever). This is so common, it adds up to a lot of work (tens of thousands of teachers pasting hundreds of URLs).

I don’t know if this wass the use case the folks at IMS had in mind when they wrote the new Content Item Message spec, but they could have. The new spec works like this:

  1. A teacher launches a “ContentItemSelection” tool from her learning system.
  2. Using the tool, she finds something she wants all her kids to use in the classroom and clicks on it.
  3. The ContentItemSelection tool sends the URL—and everything needed to LTI Launch the resource—back to their learning system.

That’s it. Done. No copy and paste. No “Create Link” forms to fill in. No strange codes to look up.

When she, or any of her kids, launches the resource; all the relevant LTI information is sent along so resource acts appropriately. For example, it may appear in “teacher mode” when teacher launches the resource, but in “game mode” when students launch it.

I have a simple example running on http://consumer.azurewebsites.net that you are welcome to play with. Here’s a short movie showing how easy it is http://screencast.com/t/HsTdm06V2l6I. Don’t blink or you’ll miss it.

Source code for my sample websites can be found at http://ltisamples.codeplex.com.

Posted in Uncategorized | Tagged , | Leave a comment

Sample LTI Provider 1.3

It took a while, but I finally updated the sample Provider website to version 1.3. The source code is here. Like the sample Consumer, the Provider project is now complete. Previous versions were missing files because I did not want to share my passwords to things like the Twitter API. But that made it hard for people to get started. So…I removed the passwords from the files. Some of the other changes:

  • Replaced SimpleMembership with Microsoft ASP.NET Identity 1.0.
  • Removed 3rd party signin support (so I could include all the project files without sharing my credentials).
  • Replaced most LTI code with LtiLibrary.
  • Converted to bootstrap (previous versions used jQuery UI).

I apologize to everyone that added Consumers or Tools to the sample provider site. Because the conversion to ASP.NET Identity changed so many tables, I gave up trying to migrate and wiped out the database.

Have fun!

Posted in Uncategorized | Tagged , , | Leave a comment

Sample LTI Consumer 1.3

I just updated the sample Consumer website to version 1.3. The source code is here. The biggest change is that the Consumer project is now complete. Previous versions were missing files because I did not want to share my passwords to things like the Twitter API. But that made it hard for people to get started. So…I removed the passwords from the files. Some of the other changes:

Despite all these changes, the website itself looks and acts pretty much like it did before.

Have fun!

Posted in Uncategorized | Tagged | 3 Comments

LtiLibrary is now a NuGet Package

To make it even easier to add IMS LTI support to your learning app, I wrapped LtiLibrary into its own NuGet Package. To add LtiLibrary to your application, run the following command in the Package Manager Console:

PM> Install-Package LtiLibrary

There is also an LtiLibrary.Sample package which adds sample MVC and Web Forms to an empty ASP.NET Web Application.

PM> Install-Package LtiLibrary.Sample

Using the LtiLibrary.Sample Package

Want to poke around a simple sample application? Try this:

  1. In Visual Studio start a New Project.
  2. Select the ASP.NET Web Application template:
    New Project dialog in Visual Student 2013
  3. Select the Empty template and add folders and core references for Web Forms, MVC, and Web API:
    New ASP.NET Web Application dialog in Visual Student 2013
  4. After the project is created, enter the following command in the Package Manager Console to install LtiLibrary.Sample:
    Package Manager Console in Visual Studio 2013
  5. Run the project and click on the Launch link to launch a sample tool.
    LtiLibrary.Sample MVC home page

LtiLibrary.Sample has MVC, Web Forms, and Web API sample code that implements LTI 1.0, 1.1, and draft 1.2 services. Here is a table of contents for the sample files:

  • LTI 1.0 Tool Consumer and Tool Provider
    • MVC
      • Tool Consumer
        • Controllers\ConsumerController.cs
        • Views\Consumer\Launch.cshtml
      • Tool Provider
        • Controllers\ProviderController.cs
        • Views\Provider\Tool.cshtml
    • Web Forms
      • Tool Consumer
        • WebForms\Launch.ashx
      • Tool Provider
        • WebForms\Tool.aspx
  • LTI 1.1 Outcomes Service
    • Web API and MVC
      • Tool Consumer
        • Controllers\OutcomesApiController.cs
      • Tool Provider
        • Views\Provider\Outcomes.cshtml
  • LTI 1.2 Tool Consumer Profile
    • Web API
      • Tool Consumer
        • Controllers\ToolConsumerProfileApiController.cs

If you are looking for a more robust example of a Tool Consumer and Tool Provider, check out the LtiSamples code in CodePlex.

Let me know if you find this useful.

Posted in Uncategorized | Tagged , , , , , | 7 Comments

Quickly add LTI consumer outcomes support to your ASP.NET MVC web site

The IMS LTI™ outcomes service allows consumers (such as Learning Management Systems) and providers (such as an online test) to send score information back and forth. Teachers love this! No more manually entering grades into the gradebook.

In this post, I show how to use my .NET LtiLibrary to add consumer outcomes support. My previous post, Quickly add LTI consumer functionality to your ASP.NET MVC web site, describes how to add the LtiLibrary project to your solution.

Add WebApi support to your web site

Use the Package Manager to add WebApi support to your web site project,

image

Then add a WebApiConfig class to the App_Start folder. If you already have one, be sure to enable the XmlSerializer (LTI outcomes use XML formatting),

using System.Web.Http;

namespace WebApplication1
{
   public static class WebApiConfig
   {
      public static void Register(HttpConfiguration config)
      {
         // Use XmlSerializer instead of DataContractSerializer
         config.Formatters.XmlFormatter.UseXmlSerializer = true;

         config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
            );
      }
   }
}

And finally, be sure to call WebApiConfig.Register when the web site starts,

using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace WebApplication1
{
   public class MvcApplication : System.Web.HttpApplication
   {
      protected void Application_Start()
      {
         // This needs to appear before the non-api routes
         WebApiConfig.Register(GlobalConfiguration.Configuration);

         AreaRegistration.RegisterAllAreas();

         FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
         RouteConfig.RegisterRoutes(RouteTable.Routes);
         BundleConfig.RegisterBundles(BundleTable.Bundles);
      }
   }
}

Implement an OutcomesController

LtiLibrary contains an abstract OutcomesControllerBase with 4 methods that you need to override:

  • GetConsumerSecrets – Return the list of secrets for the given OAuth consumer key. These will be used to validate the outcomes service call from the provider.
  • DeleteResult – Delete the specified score.
  • ReadResult – Read the specified score.
  • ReplaceResult – Save the specific score.

Here is a simple example that works with the IMS LTI™ test tool,

using System.Collections.Generic;

namespace WebApplication1.Controllers
{
   public class OutcomesController : LtiLibrary.Consumer.OutcomesControllerBase
   {
      private static double? Score;

      protected override bool DeleteResult(LtiLibrary.Consumer.Result result)
      {
         Score = null;
         return true;
      }

      protected override IList<string> GetConsumerSecrets(string consumerKey)
      {
         return consumerKey.Equals("12345") ? new List<string> { "secret" } : new List<string>();
      }

      protected override bool ReadResult(LtiLibrary.Consumer.Result result)
      {
         result.DoubleValue = Score;
         return true;
      }

      protected override bool ReplaceResult(LtiLibrary.Consumer.Result result)
      {
         Score = result.DoubleValue;
         return true;
      }
   }
}

Tell the provider that you support outcomes

The last step is to tell the provider that you support outcomes. You do this by adding two values to the LTI request: the endpoint URL of the outcomes service, and the result ID which you can think of as the grade cell ID in the grade book. For example,

public ActionResult Launch()
{
   var request = new LtiLibrary.Consumer.LtiOutboundRequest
      {
         ConsumerKey = "12345",
         ConsumerSecret = "secret",
         ContextId = "1",
         ResourceLinkId = "1",
         Url = "http://www.imsglobal.org/developers/LTI/test/v1p1/tool.php"
      };

   // Add outcomes support
   var urlHelper = new UrlHelper(this.HttpContext.Request.RequestContext);
   var relativeUrl = urlHelper.HttpRouteUrl("DefaultApi", new { controller = "outcomes" });
   request.LisOutcomeServiceUrl = new Uri(this.HttpContext.Request.Url, relativeUrl).AbsoluteUri;
   request.LisResultSourcedId = "1";

   return View(request.GetLtiRequestModel());
}

Launch

If you launch the IMS LTI™ test tool, you will see a new option to test outcomes,

image

What’s Next?

Check out the sample Consumer in LTI Samples to see a more robust use of LtiLibrary. If you are a publisher, the sample Provider shows how to use LtiLibrary to handle LTI launch requests and even send grades back to the consumer.

Posted in Uncategorized | Tagged , , | 4 Comments

Quickly add LTI consumer functionality to your ASP.NET MVC web site

NOTE: This post is obsolete. LtiLibrary is now on GitHub, along with several samples.

IMS LTI™ is a technology which helps one educational system interoperate with another. For example, a Learning Management System (LMS) can launch an educational tool with enough context that the tool knows if the user a student or teacher, which institution they belong to, and even which course section they are enrolled in.

In this post, I show how to use my .NET LtiLibrary to make a simple LTI request to launch the IMS LTI™ test tool.

Get LtiLibrary from CodePlex

LtiLibrary is a project within LTI Samples on CodePlex. LTI Samples has two complete sample web sites: a Consumer and a Provider. But for this example, you only need the LtiLibrary project.

You will notice that LtiLibrary depends on EntityFramework, HtmlAgilityPack, and OAuth.net. The easiest way to get EntityFramework and HtmlAgilityPack is with nuget. You will have to download and unzip OAuth.net the old fashioned way.

Make sure you can build the LtiLibrary project before you continue.

SNAGHTML1ae6907

Hook Up LtiLibrary to Your Web Site

First add a reference to the LtiLibrary project to your ASP.NET MVC web site project, then add a new Action called Launch to one of your controllers:


public ActionResult Launch()
{
  var request = new LtiLibrary.Consumer.LtiOutboundRequest
  {
    ConsumerKey = "12345",
    ConsumerSecret = "secret",
    ContextId = "1",
    ResourceLinkId = "1",
    Url = "http://www.imsglobal.org/developers/LTI/test/v1p1/tool.php"
  };
  return View(request.GetLtiRequestModel());
}

Now add the corresponding View (e.g. Launch.cshtml) to post the LTI launch request:

@model LtiLibrary.Consumer.LtiOutboundRequestViewModel

<form id="form" action="@Model.Action" method="post">
  @foreach (var name in Model.Fields.AllKeys)
  {
    <input type="hidden" name="@name" value="@Model.Fields[name]" />
  }
  <input type="hidden" name="oauth_signature" value="@Model.Signature" />
</form>

@section Scripts {
  <script>
    $(function () {
      $("#form").submit();
    });
  </script>
}

And finally, add a link or button that invokes the Action:

image

Launch

When you click on the link or button, you should see IMS LTI™ test tool appear and display details of your request:

image

What’s Next?

Check out the sample Consumer in LTI Samples to see a more robust use of LtiLibrary. If you are a publisher, the sample Provider shows how to use LtiLibrary to handle LTI launch requests and even send grades back to the consumer.

Posted in Uncategorized | Tagged , | 2 Comments