Author Archives: Justin

Strategies for Versioning Your RESTful API

The annual Raleigh Code Camp was a great time and the most attended one yet.  This year I presented “Strategies for Versioning Your RESTful API” to a larger room of attendees than I was expecting.  It’s sort of a niche topic, but more API developers are discovering they need a plan for versioning their RESTful APIs as they evolve.  Thanks for all that attended; there was good conversation showing that REST is indeed a topic open to interpretation.

My slide deck can be seen here:

The versioning samples I ran were run in ASP.NET Web API 2 and can be found on GitHub.

Tags: , Filled Under: Programming Posted on: November 10, 2014

Can’t Install NuGet Package Because of “Failed to initialize the PowerShell host”

I was attempting to install the Newtonsoft.Json v. 6.0.4 NuGet Package in a project and received an error message beginning with the text, “Failed to initialize the PowerShell host…”.  Interesting.  I know the PowerShell execution policy can be restrictive by default so I opened Visual Studio 2013’s Package Manager Console and entered the command:

Get-ExecutionPolicy

It came back as RemoteSigned.  RemoteSigned **should** be fine for this package and for any package in the public NuGet feed.  I thought perhaps something was overlooked in the signing of the published package so I changed the execution policy in my Package Manager Console (note: Visual Studio has to be run as Administrator to do this).

Set-ExecutionPolicy Unrestricted

An Unrestricted policy doesn’t care if the package is signed or not; it’s a run-at-your-own-risk setting.  But still, I received the same error!  I ran Get-ExecutionPolicy and noticed it was still set to RemoteSigned.  So it was time to do some Goggling and I ran across a great StackOverflow answer and accompanying comment for this same problem.  The poster to the answer stated,

Be aware that changes will be applied according to the bit version of the PowerShell console, so 32bit or 64 bit.

I use a 64 bit environment so this had to be the problem!  A commenter to that StackOverflow answer posted how to actually do this in the Package Manager Console:

start-job { Set-ExecutionPolicy Unrestricted } -RunAs32 | wait-job | Receive-Job

Once I ran that, Get-ExecutionPolicy returned Unrestricted.  I made another attempt to install the NuGet package and it worked!

Tags: Filled Under: Programming Posted on: September 26, 2014

Interacting With The YouTube iFrame API

YouTube Player APIs

Displaying a YouTube video within a web app is easy; controlling events like starting the video and detecting when it ended gets a little more involved.  Luckily YouTube has player tools that include Player APIs.  For web applications there are currently three Player API choices: the IFrame API; the JavaScript API; and the Flash API (AS3).  These APIs allow the consumer fine-grained control over the Player including the visibility of Player controls, configuring the Player size, and perhaps most importantly, listening to Player events such as start, stop, etc.  All of these exposed items can be seen in action in the YouTube Player Demo.

Choosing a Player API

I was developing a site where it was required that the user watched a specified YouTube video through completion until being allowed to continue on to another page of a web site.  To get started, I had to choose what YouTube API library would work best in this situation.  Given that I couldn’t expect all end users to have Flash installed, I knew right away that the Flash API was out.  Flash is out the door as a technology and most mobile devices don’t support it in favor the HTML5 player.

The IFrame Player API

With the Flash API out, this leaves the iFrame API and the JavaScript API.  Given its name, one may assume that the JavaScript API is the most modern API and may provide HTML5 capabilities, but it doesn’t.  Listed in the requirements for the YouTube JavaScript API is:  “The end user must have Flash Player 10.1 or higher installed to view everything correctly.”.  So that leaves the IFrame API.  To me, the use of an IFrame seems a bit dated, but the API name is sort of a misnomer.  It’s in fact the newest YouTube Player API and it is completely controllable via – you guessed it, JavaScript!

True to its name, the YouTube Player IFrame API does post content to an <iframe> tag on the page that serves an HTML5 player or Flash player depending on the capabilities of the client browser.  It is very simple to use and the documentation even has a great getting started guide complete with a working code sample:

<!DOCTYPE html>
<html>
  <body>
    <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
    <div id="player"></div>

    <script>
      // 2. This code loads the IFrame Player API code asynchronously.
      var tag = document.createElement('script');

      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

      // 3. This function creates an <iframe> (and YouTube player)
      //    after the API code downloads.
      var player;
      function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
          height: '390',
          width: '640',
          videoId: 'M7lc1UVf-VE',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }

      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        event.target.playVideo();
      }

      // 5. The API calls this function when the player's state changes.
      //    The function indicates that when playing a video (state=1),
      //    the player should play for six seconds and then stop.
      var done = false;
      function onPlayerStateChange(event) {
        if (event.data == YT.PlayerState.PLAYING && !done) {
          setTimeout(stopVideo, 6000);
          done = true;
        }
      }
      function stopVideo() {
        player.stopVideo();
      }
    </script>
  </body>
</html>

However, not all samples fit all situations.  This sample defines an OnReady event on line 24 that in turn defines a  function named OnPlayerReady.  That OnPlayerReady function is using a command on line 32 to play the video.  This is setting up the video to autoplay when the page loads.  This works great unless you are on an iOS or modern Android device.  Apple specifically disallows autoplay of audio and video on iOS devices in an effort to preserve any of the user’s possible data usage limitations.  What you instead get is the YouTube Player loads and then the screen goes black and no playback controls are visible.

Special Considerations for iOS and Android

Given that attempting to autoplay a video on iOS or Android causes the player to enter an error state, there’s a need to detect if the client’s user agent is iOS or Android and not autoplay the video.  The user will instead have to push the play button on the YouTube Player.  This can be accomplished by modifying the OnPlayerReady function to detect this:

function onPlayerReady(event) {
    var iOS = /(iPad|iPhone|iPod|Android)/g.test(navigator.userAgent);
    if (!iOS) {
        event.target.playVideo();
    }
}

Detecting When The Video Has Ended

In this sample, the onPlayerStateChange function is assigned to the Player’s onStateChange event.  It is here where player events are captured and can be put to use.  In my case, there was a requirement to somehow track that the user had watched the video to completion in order to visit a certain other page.  This can be accomplished by first creating a session cookie when the player detects the video has Ended.

var done = false;
function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.ENDED && !done) {
        // create session cookie indicating video watched
        document.cookie = "trackview=watched; expires=0; path=/" // using expires=0 sets a session cookie
        done = true;
    }
}

Verifying The Video Was Watched

At this point the iFrame Player is capturing the Ended state of the video and then issues a session cookie.  Now on the page that needs to ensure that the cookie exists, a check can be placed on its window.onload event:

function checkCookie() {
    var x = readCookie('watched');
    if (!x) {
        document.location.href = "/";
    }
}

window.onload = checkCookie;

Here if the cookie doesn’t exist, the user is being sent back to the site root.  If the cookie does exist a general assumption can be made that the user was issued the cookie when the video was watched to completion, thanks to the YouTube IFrame API event that we subscribed to.

Tags: Filled Under: Programming Posted on: August 11, 2014

FluentValidation With WebAPI 2

The GitHub project description for FluentValidation is succinct and explains what it does better than I could paraphrase:

A small validation library for .NET that uses a fluent interface and lambda expressions for building validation rules for your business objects. 

This is a great open-source library that I’ve been using for years.  One of the things that makes this a great library is its constantly evolving.  Support for the ever-increasing versions of ASP.NET MVC have been kept up to date.  Until recently there was no official support for ASP.NET WebAPI, but that too has changed.

WebAPI 2 support has been released, however the official documentation on CodePlex hasn’t yet been updated to reflect that.  Luckily the documentation for FluentValidation’s ASP.NET MVC integration is there because it’s a good starting point.  However, instead of working with an MVC controller, let’s work with an ApiController.

First, here is a User object and our User validator class:

[Validator(typeof(UserValidator))]
public class User
{
	public int Id { get; set; }
	public string Email { get; set; }
	public string FirstName { get; set; }
	public string LastName { get; set; }
}

public class UserValidator : AbstractValidator<User>
{
	public UserValidator()
	{
		RuleFor(x => x.Id).NotNull();
		RuleFor(x => x.Email).EmailAddress();
	}
}

The validation rules defined above state that a User object can’t have a null Id and the EmailAddress must be a valid email.  Next, create an API controller.  Here is a POST method that will validate the ModelState.  If validation fails, an HttpResponseException will be thrown.  If validation is successful, you would do whatever processing you need (insert/update/etc) and then return a response.

public class UserController : ApiController
{
	public HttpResponseMessage Post(User user)
	{
		if (!ModelState.IsValid)
		{
			// validation failed; throw HttpResponseException
			throw new HttpResponseException(
				new HttpResponseMessage
					{
						StatusCode = HttpStatusCode.BadRequest,
						ReasonPhrase = "Validation failed."
					});
		}

		// validation passed; process record and return success
		return this.Request.CreateResponse(HttpStatusCode.OK);
	}
}

Now that the validator is defined and there’s an API controller, how does WebAPI know to process the validation for the API method’s ModelState?  In the Global.asax’s Application_Start event, the FluentValidationModelValidateProvider needs to be configured (line 10):

protected void Application_Start()
{
	AreaRegistration.RegisterAllAreas();
	GlobalConfiguration.Configure(WebApiConfig.Register);
	FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
	RouteConfig.RegisterRoutes(RouteTable.Routes);
	BundleConfig.RegisterBundles(BundleTable.Bundles);

	// configure FluentValidation model validator provider
	FluentValidationModelValidatorProvider.Configure(GlobalConfiguration.Configuration);
}

If the FluentValidationModelValidateProvider isn’t configured, all ModelState validation checks would return an IsValid value of true, even if validation rules were not met.

Let’s see this in action.  Here is a request that contains an invalid formatted email address:

Invalid HTTP request.

HTTP request with an invalid email address that doesn’t pass validation.

The response is an HTTP 400 indicating that validation failed.  Trying again with a correctly formatted email address returns a successful HTTP status code:

Valid HTTP request

HTTP request with a valid User model passes validation.

Here, validation of the User object was successful and an HTTP 200 was returned from the API controller indicating success.

Tags: Filled Under: Programming Posted on: July 15, 2014

Getting HttpResponseException Details for Your WebAPI Unit Tests

For .NET unit testing assertions, I use Fluent Assertions.  Not only does it result in easier to read assertions, but it makes it easy to dig down in to the details of an exception.  This is particularly important for something like an HttpResponseException that can contain a complex object such as an HttpResponseMessage.  The HttpResponseMessage will have properties that you may want to test such as StatusCode and ReasonPhrase.

FluentAssertions documentation doesn’t (that I know of) show how to get  an object within an exception.  So this post is a reminder to myself of how to do just that.

Here is a simple ASP.NET WebAPI HTTP POST method that performs division.  It’s doing a check to safeguard against a caller attempting to divide by zero.  In the case the caller does attempt to divide by zero, an HttpResponseException is thrown.  The HttpResponseException contains an HttpResponseMessage with a 400 status code along with a reason.

[HttpPost]
public decimal DivideNumber(decimal dividand, decimal divisor)
{
    if (divisor == 0)
    {
        // can't divide by zero
        throw new HttpResponseException(new HttpResponseMessage { StatusCode = HttpStatusCode.BadRequest, ReasonPhrase = "The divisor cannot be zero." });
    }

    return dividand / divisor;
}

To test this, I’d like to verify that the HttpResponseException is thrown and it contains an HttpResponseMessage with an HttpStatusCode of 400 (Bad Request) and the contained reason phrase.  The variable named result is the HttpResponseException.  The result then contains a Response which is the HttpResponseMessage.  The Response then makes it possible to test the properties of the HttpResponseMessage as shown below:

[TestMethod]
public void DivideNumber_WithZeroDivisor_ShouldReturnHttp400()
{
    // Arrange
    const decimal dividand = 10.0m;
    const decimal divisor = 0.0m;
    var controller = new SampleController();

    // Act
    Action ax = () => controller.DivideNumber(dividand, divisor);

    // Assert
    var result = ax.ShouldThrow<HttpResponseException>();
    result.And.Response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
    result.And.Response.ReasonPhrase.Should().Be("The divisor cannot be zero.");
}

Don’t forget to reference FluentAssertions in your unit test project.  It’s available on NuGet.

Tags: Filled Under: Programming Posted on: April 25, 2014