Building a Web API 2 project from scratch using OWIN/Katana .NET Part 4: async controllers and mini-DDD

Introduction

In the previous post we briefly looked at a new hosting project by Microsoft called Helios. It is meant to be the future of web application deployment where Helios removes the necessity of having the entire System.Web dependency in your web project. We saw that Helios is only in a preview state so it shouldn’t be used for real-life projects yet.

In this post we’ll diverge from OWIN/Katana and instead see how we can add asynchronous controller methods to our current CustomersApi web project. We’ll also build a miniature version of a layered application. We’ll put the layers into separate folders for simplicity.

Read more of this post

Advertisements

Building a Web API 2 project from scratch using OWIN/Katana .NET Part 3: hosting on Helios

Introduction

In the previous post we discussed how to use OWIN host to self-host a Web API 2 application. We saw how easy and straightforward it was to install the OWIN hosting package with NuGet.

In this post we’ll look at another hosting option: Helios.

Read more of this post

Building a Web API 2 project from scratch using OWIN/Katana .NET Part 2: OWIN host

Introduction

In the previous post we saw how to build a simple Web API from scratch using a couple of OWIN/Katana components. We added a couple of Katana libraries from NuGet, wired up the routing from the Startup class and we were good to go.

In this post we’ll see one way to make the application run independently of IIS. As we stated before an important benefit of this new OWIN infrastructure is that you can make your ASP.NET web application run on multiple hosts, not only IIS. IIS is only one of the options.

Read more of this post

Building a Web API 2 project from scratch using OWIN/Katana .NET Part 1

Introduction

If you’re a .NET developer then you must have come across the new light-weight web framework standard called OWIN. Its implementation by Microsoft in .NET is called Katana. We’ve looked at OWIN/Katana on this blog already starting here. I won’t go through the same exact same topic in this new series. Instead we’ll concentrate on the basic components that are required at a minimum to build a functioning, platform independent Web API 2 project.

If you’ve read other posts on this blog then you’ll know about my preference for web services as opposed to shiny GUI development á la ASP.NET MVC. Also we’ll be looking into other Web API 2 features in OWIN later on so this will be a good foundation.

Read more of this post

Introduction to .NET Web API 2 with C# Part 3: authentication

Introduction

So far in this intro course we haven’t discussed authentication although we enabled it when we created the demo Web Api app. In this demo we’ll see how to make an authenticated request to the API. Let’s imagine that our rockband data is top secret. Therefore not just anyone should gain access to it.

Open the demo app and the simple HTML web app we’ve been working on and let’s get started.

Authentication

Recall from the previous post in this series that we made an anonymous call to the API via the Get Rockbands button from the HTML web app. We’ll see how the need of authentication changes the picture.

Open RockbandsController.cs and place the following attribute over the class declaration:

[Authorize]
public class RockbandsController : ApiController

Run both apps. Have the Chrome developer tools open in the browser for default.html. Press the Get Rockbands button and you should get a 401 back:

Unauthorised Web API

So we’ll need to authenticate first. However, in order to authenticate we’ll need to sign up with the API app. However, there’s no familiar Signup link as the API page is not the usual MVC page with the login and sign-up links in the top right hand corner. Navigate to /Help on the Web API page to view the available HTTP endpoints. You’ll find a number of actions under the Account category. The POST api/account/register entry looks promising. Click on that link to view what we need to send to the service:

User registration inputs

That doesn’t look terribly difficult. Let’s build a simple UI for that in the HTML web app. Place the following HTML below the h1 tags:

<form id="userSignup">
        <input type="text" name="username" placeholder="Name" />
        <input type="password" name="password" placeholder="Password" />
        <input type="password" name="confirmpassword" placeholder="Confirm password" />
        <input type="submit" id="signup" value="Sign up" />
</form>

Note the “name” attributes of the input tags. They correspond to the properties in the JSON that the Register action expects. The case doesn’t matter: userName, USERNAME, etc. will all do the job.

We’ll now need some javascript to send the data to the service. It’s good that we set up CORS in the previous post so we can call the service from here. We already have some javascript on that page to get the rockband data. Place the following bit of code…

var register = function () {
                var registrationUrl = "http://localhost:50170/api/Account/Register";
                var registrationData = $("#userSignup").serialize();
                $.post(registrationUrl, registrationData).always(showRockbands);
                return false;
            };

$("#signup").click(register);

…above…

$("#getRockbands").click(getRockbands);

We call the Register controller with a POST request and send the serialised form data in the message body. We’ll show the response using the showRockbands method we defined earlier. Re-run default.html and try to register without filling in the form:

Validation exception

Not surprisingly we get a validation exception.

Fill in the text boxes and you should get an empty response which means that the request succeeded:

Web API signup OK

So we’re registered but we still cannot access the rockband data. We’ll need to send along an access token. In fact we need to send it along with every request that requires authentication. It’s not the same as a cookie in the case of forms authentication. Instead, we’ll need to send the token in the request header. This is done by logging in with the website using the login credentials and get hold of the access token from the website. If you look at the Help page again in the API app you won’t find any logical candidate for this task. There’s no “login” or “gettoken” endpoint.

The secret is hidden in a completely different place. Locate Startup.Auth.cs in the App_Start folder. This file uses OWIN technology. I’m planning to write a short series on OWIN and KATANA later in case you’re interested in those technologies. The interesting bit of code is the following:

OAuthOptions = new OAuthAuthorizationServerOptions
{
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
                AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                AllowInsecureHttp = true
};

The ‘/Token’ bit looks promising. We’ll need to send a POST to /Token with our credentials which will return an access token. You can even test it in a browser, but it won’t succeed of course:

Missing token

This means that we need to specify a grant type which is missing, hence the “unsupported grant type” error message. The endpoint is expecting some data called “grant_type=[type of grant]”. Let’s see how we can build that.

Add the following piece of HTML to the form on the HTML page:

<form id="userSignup">
        <input type="text" name="username" placeholder="Name" />
        <input type="password" name="password" placeholder="Password" />
        <input type="password" name="confirmpassword" placeholder="Confirm password" />
        <input type="submit" id="signup" value="Sign up" />
        <input type="submit" id="signin" value="Sign in" />
</form>

Our form will also function as a login form. Not a very practical solution but it will do for demo purposes.

Add the following bit of JavaScript…:

var signin = function () {
                var tokenUrl = "http://localhost:50170/Token";
                var loginData = $("#userSignup").serialize();
                loginData = loginData + "&grant_type=password";
                $.post(tokenUrl, loginData).always(showRockbands);
                return false;
            };

$("#signin").click(signin);

…above…

$("#signup").click(register);

We’re calling the /Token endpoint and send along a grant type of password. This is telling the endpoint that we need an access token based on the username and password in the form data.

Run both applications and fill in the username and password you signed up with in the previous step. You should see… …the same error as we saw before we enabled CORS. But didn’t we enable CORS already? Yes, but that was in the context of the Web API. We need to do something similar for the /Token endpoint which hides OWIN middleware. Locate ApplicationOAuthProvider.cs in the Providers folder of the Web API project. Search for the following method:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)

You’ll see a using block in the method body. Add the following code below the using block:

context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

Re-run the web api demo app and try to sign in. It should succeed and the token should be visible on the screen:

Bearer token from web api

You’ll find a short course on OAuth here which explains what the parts in this JSON mean if you’re curious. The most important bit of information is the access_token. We’ll need to extract it from the JSON and send it along with every subsequent request to the API. This will allow the request through the Authorize attribute. Modify the JavaScript code…

$.post(tokenUrl, loginData).always(showRockbands);

…to the following:

$.post(tokenUrl, loginData)
                    .success(saveAccessToken)
                    .always(showRockbands);

…where saveAccessToken is defined as follows:

var token = "";

var saveAccessToken = function (data) {
      token = data.access_token;
};

We save the access_token property from the JSON that came back from the web api auth request.

Replace…

var getRockbands = function () {
         $.get(rockbandSourceUrl).always(showRockbands);
         return false;
};

…with an AJAX request:

var getRockbands = function () {
                $.ajax(rockbandSourceUrl,
                {
                    type: "GET"
                    , headers: getHeaders()
                }).always(showRockbands);
                return false;
};

…where getHeaders() is defined as follows:

var getHeaders = function () {
                if (token){
                    return { "Authorization": "Bearer " + token };
                }
};

Re-run the HTML app and login first. Wait for the access token to appear. Then click Get Rockbands and there you are:

Rockbands OK after login

This is slightly more complicated than it should be but it may change in the future. There’s actually a readily available single-page version of we’ve just done among the MVC 5 templates.

If you create a new ASP.NET Web application in Visual Studio you can select the Single Page Application template:

Single page application

It will set up authentication, MVC, Web API, OWIN, jQuery and knockout.js for you for a fancy start-up single page application. Start the application and click on the links. It looks like you’re navigating through controllers but it’s really the same page where knockout.js takes care of showing and hiding different parts on the UI. You can sign up with a username and password and then you’ll see a familiar view but now with the usual welcome message and the Log off link in the top right hand corner:

Single page login Web API

The signup function uses the Account controller and a POST to the /Token endpoint like we did above.

You can view the list of posts on Security and Cryptography here.

View the list of MVC and Web API related posts here.

Introduction to .NET Web API 2 with C# Part 1

Introduction

Web API has been around for some years now. It is a very efficient and lightweight technology to build RESTful web services in .NET. Web API is very similar to .NET MVC with its controllers and routing rules. Therefore if you are familiar with MVC then it’s not too difficult to get going with Web API either.

If you are not familiar with Web API at all then I suggest that you first go through the basics using the link provided above. There are some good courses available there as well.

In this short series on Web API 2 we’ll discuss some of the new options available compared to the “original” Web API package.

Demo

I’m building the demo using Visual Studio 2013 Express for Web. You can probably do the same in VS 2012 by downloading the MVC 5 templates. So open VS2013 and create a new ASP.NET web project called RockbandData:

Web API 2 new project

Click OK and then select the Web API template:

Web API 2  template

Notice that it says ‘No authentication’ on the right side of the window. We’ll change that so click Change Authentication. Select the Individual User Accounts option in the Change Authentication window and click OK. Click OK again on the New ASP.NET Project window so that Visual Studio can create the project. It takes some time but eventually you’ll have a project structure like this:

Default project structure Web API 2

You can immediately run the project by pressing F5 and you’ll see a default web site popping up in your browser:

Web API 2 default homepage

It looks like a normal MVC website. However, there are some differences between a “real” MVC default website and its Web API counterpart. Even if we stated that we require authentication there’s no link to log in or sign up new users anywhere. The reason is that the standard MVC AccountController controller is not available. User login and signup is handled in a slightly different way which we’ll explore later.

Documentation page

What’s new is a link that says ‘API’ up in the navigation bar. Click on it and you’ll see that a list of possible URLs appears in a table:

Web API 2 default help page

This is a documentation page for the available URL endpoints of the web service. Click on one of the URLs and you’ll see an example for the JSON and XML response structures:

Sample return values

If you check out one of the POST urls then the documentation will show you the expected request body format as well:

RequestBodyDocumentation

The documentation is provided by a pre-installed NuGet package: Microsoft.AspNet.WebApi.HelpPage. It will look for ApiControllers in your project and any documentation available on them using Reflection. You won’t find an assembly reference to this package under the References section so don’t look for it. However, there’s a HelpPage area in the solution:

Web API 2 Help Page area

The controllers, models and views in this area help construct the Documentation page we’ve just seen. Any new API controller you create will be added to the documentation. You can add comments in the usual way: just decorate the Controller with VS XML comments:

/// <summary>
/// This the Get all values method within the ValuesController
/// </summary>
/// <returns>A sequence of strings</returns>
public IEnumerable<string> Get()
{
     return new string[] { "value1", "value2" };
}

Also, you need to let VS generate an XML documentation file:

Add XML documentation to page

We’re not done yet. Locate the HelpPageConfig.cs file in the Areas/HelpPage/App_Start folder. There will be some code already but it’s all commented out. Uncomment the first line and modify the file name to match what you provided in the previous step:

config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath("~/App_Data/RockbandData.xml")));

Rebuild and run the project. If you get a runtime exception saying that the documentation XML file wasn’t found then check the file URL again in the code we’ve just commented out. It may have been overwritten. The documentation page should show the new description:

Description updated

Values controller

You can call the values controller in the browser to check if the Get() method is working. The URL should be http://localhost:50170/api/values. The port number in your case may of course differ. At first you should get an error message saying that the request was unauthorised. That’s because the ValuesController has been decorated with the [Authorize] attribute. Uncomment it and refresh the page. You should see an XML with the default values returned.

Model data

Any demo on the Web API is futile without a data source. Let’s build a class hierarchy in the Models folder. Note that your domains should exist in a separate project of course but this post is not about layered architecture but the Web API. If you are interested in layered projects then check out the series on Domain Driven Design and/or SOA.

Also, to avoid wasting too much time setting up the data source in e.g. Entity Framework or MongoDb we’ll be working with in-memory data.

Locate the Models folder and add a new folder in it called Domain. We’ll build a simple data hierarchy around rock music. Add the following classes to the Domain folder:

public class Prize
{
    public string Name { get; set; }
}
public class Album
{
    public string Title { get; set; }
    public int Year { get; set; }
}
public class RockBand
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Album> Albums { get; set; }
    public ICollection<Prize> Prizes { get; set; }
}

Next we’ll set up the in-memory repository to get some data to start with. Again, all this is violating every principle behind SOLID and layered architectures but I don’t want to get sidetracked. We’ll set up an in-memory data context which has the same function as the DbContext object you might be familiar with from EntityFramework. We’ll use the singleton pattern to get hold of the object context instance.

Insert a new folder called Repository. Add the following object context “simulation”:

public class InMemoryDatabaseObjectContext
{
        private List<RockBand> _rockBands;

        public InMemoryDatabaseObjectContext()
        {
            _rockBands = InitialiseRockBands();
        }
        
        public IEnumerable<RockBand> GetAll()
        {
            return _rockBands;
        }

        public static InMemoryDatabaseObjectContext Instance
        {
	     get
	     {
		   return Nested.instance;
	     }
        }

        private class Nested
        {
	     static Nested()
	     {
	     }
	     internal static readonly InMemoryDatabaseObjectContext instance = new InMemoryDatabaseObjectContext();
        }

        private List<RockBand> InitialiseRockBands()
        {
            List<RockBand> rockbands = new List<RockBand>();

            RockBand greatBand = new RockBand();
            greatBand.Name = "Great band";
            greatBand.Id = 1;
            greatBand.Albums = new List<Album>(){new Album(){Title = "First album", Year = 2000}, new Album(){Title = "Second album", Year = 2003}
                , new Album(){Title = "Third album", Year=2005}};
            greatBand.Prizes = new List<Prize>() { new Prize() { Name = "Best band" }, new Prize(){Name = "Best newcomers"} };

            RockBand rockBand = new RockBand();
            rockBand.Name = "Funny band";
            rockBand.Id = 2;
            rockBand.Albums = new List<Album>(){new Album(){Title = "Debut", Year = 1979}, new Album(){Title = "Continuation", Year = 1980}
                , new Album(){Title = "New Year", Year=1982}, new Album(){Title ="Summer", Year=1985}};
            rockBand.Prizes = new List<Prize>() { new Prize() { Name = "Cool band" }, new Prize() { Name = "Best band" }, new Prize(){Name = "First choice"} };

            RockBand anotherBand = new RockBand();
            anotherBand.Name = "Sounds good";
            anotherBand.Id = 3;
            anotherBand.Albums = new List<Album>(){new Album(){Title = "The beginning", Year = 1982}, new Album(){Title = "The end", Year = 1986}};
            anotherBand.Prizes = new List<Prize>() {new Prize() { Name = "First choice" } };

            RockBand rb = new RockBand();
            rb.Name = "Sounds good";
            rb.Id = 4;
            rb.Albums = new List<Album>() { new Album() { Title = "Cool", Year = 1988 }, new Album() { Title = "Yeah", Year = 1989 }
                , new Album() { Title = "Oooooohhh", Year = 1990 }, new Album() { Title = "Entertain", Year = 1991 }, new Album() { Title = "Go home", Year = 1992 }};
            rb.Prizes = new List<Prize>() { new Prize() { Name = "First choice" }, new Prize() { Name = "Cool band" } };

            rockbands.Add(greatBand);
            rockbands.Add(rockBand);
            rockbands.Add(anotherBand);
            rockbands.Add(rb);

            return rockbands;
        }
}

Add the following components necessary for the thread safe lazy singleton pattern:

public interface IObjectContextFactory
{
        InMemoryDatabaseObjectContext Create();
}
public class LazySingletonObjectContextFactory : IObjectContextFactory
{
	public InMemoryDatabaseObjectContext Create()
	{
		return InMemoryDatabaseObjectContext.Instance;
	}
}

If you don’t know what these components mean the check out the link provided above about the singleton pattern. You can even ignore it for now as they are not important for the main discussion: the lazy singleton pattern will make sure that the data source will not be wiped out with every new HTTP request and that all requests will query the same object context. You’ll also see that we have some initial data with a couple of great rock bands.

We have our data store so we’d like to extract the rockband data via an API call.

Rockbands controller

Right click the Controllers folder and select Add and then Controller from the context menu. The Add Scaffold window will appear. Select the Web API 2 Controller – Empty option and click Add. In the Add Controller window insert the controller name: RockbandsController. The new controller will derive from ApiController as expected.

Add the following private field and constructor to the controller:

private IObjectContextFactory _objectContextFactory;

public RockbandsController()
{
     _objectContextFactory = new LazySingletonObjectContextFactory();
}

Another warning: DON’T DO THIS AT HOME! In a real project you’ll not consult the repository directly from a controller and you will inject the correct implementation of the IObjectContextFactory dependency through the controller constructor. If you’re wondering how to do this check out the links on DDD and SOLID provided above.

Insert the following Get() method into the controller:

public IEnumerable<RockBand> Get()
{
            return _objectContextFactory.Create().GetAll();
}

This method will be invoked if a GET request is directed to the RockbandsController using the URL /api/rockbands. Run the application and enter this URL into the browser: http://localhost:%5Byour port number]/api/rockbands. You should get an XML representation of the sequence of Rockbands:

Get all rockbands xml

Great! We have now the basis for moving forward. We’ll continue our investigation of the Web API in the next part.

View the list of MVC and Web API related posts here.

ultimatemindsettoday

A great WordPress.com site

Elliot Balynn's Blog

A directory of wonderful thoughts

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: