post image

How to Master ASP.NET Core Web API Attribute Routing

Attribute routing is a great way to keep the routing for your RESTful API’s under control. Introduced with Web API 2, Attribute Routing makes a few things simpler compared to the routing templates used in the first revision of ASP.NET Web API.

Simplification by Atribute Routing

A few of the things that got better or simpler with Attribute Routing.

Multiple Parameter Types

Attribute routing easily enables using multiple parameter types in a route. An example route taking multiple parameters:

[HttpGet("api/entity/{id:int}/{foo:length(5)}")]

In the example the id parameter is required to be an int and the foo parameter is required to be a string of 5 characters.

Versioning of an API

Versioning of APIs has always been a little tricky (and debated), but one thing attribute routing enables is to easily create versioned routes of the format:

[HttpGet("api/v1/entity/{id:int}")]

URI Segment Overloads

Having multiple HTTP GET endpoints in a controller for different URIs is easy, for ex two endpoints taking either an int or a string as the last parameter:

[HttpGet("api/entity/{id:int}")]
[HttpGet("api/entity/{foo:length(5)}")]

The Controller and Action Tokens

A problem with the ASP.NET Web API previously have been renaming of controllers or actions and any eventual string references to their name in the routes. In the ASP.NET Core Web API we’ve got a remedy for that, enter [controller] and [action] token!

Just use these tokens in any routes when you want to reference the controller or action name.

Setting a Controller Base Route

A common practice in ASP.NET Core Web API controllers is to define a base route that all the endpoints in the class will have in common. You do this by defining a route attribute just above the class declaration for the controller. Like this:

[Route("api/[controller]")]
public class ProductsController : Controller
{
   ...
}

This will make all endpoints in the controller have “/api/products/” prefixed in front of them, thus you won’t have to specify that in every methods attribute route.

Overriding a Controllers Base Route

If you want to define an endpoint without the base route in a controller that has a base route, it’s possible to use the tilde character (“~”) to override the rule.
For ex, putting the attribute route below on the Get method in the DroidsController used for the examples in this post:

[HttpGet("~/thesearethedroids")]

This template URI would make the route change from http://localhost:5000/api/droids/ to http://localhost:5000/thesearethedroids/

Anatomy of an Attribute Route

An attribute route is defined as follows:

[HttpMethod("Template URI", Name?, Order?)]

First, let’s take a look at the available Http methods in the ASP.NET Core Web API.

Http Methods

These are the currently available Http Methods in ASP.NET Core 1.0, click the link to see the documentation for each method.

HttpDeleteAttribute

Used to define a HTTP DELETE method.

HttpGetAttribute

Used to define a HTTP GET method.

HttpHeadAttribute

Used to define a HTTP HEAD method.

HttpOptionsAttribute

Used to define a HTTP OPTIONS method.

HttpPatchAttribute

Used to define a HTTP PATCH method.

HttpPostAttribute

Used to define a HTTP POST method.

HttpPutAttribute

Used to define a HTTP PUT method

The Template URI Parameter

A Route is a string describing a URI template. The template consists of literals and/or parameters, parameters are defined within curly brackets. The following is an example of a route template. In the example “droids” and “services” are literals and “{id}” is a parameter.
/droids/{id}/services/

An issue with the above template is that the “{id}” parameter is unspecified, meaning that the following routes will all match this URI template:
/droids/10/services/
/droids/true/services/
/droids/theseare/services/
/droids/1.97/services/
/droids/mobilemancer/services/
/droids/r2-d2/services/

The way to go for making the routes more specific is Routing Constraints.
A Routing Constraint is used to set rules on your parameters. For example, setting the constraint that the above example routes “{id}” parameter should be an int would be done as follows:
/droids/{id:int}/services/
More on Routing Constraints in a section below.

The Name Parameter

An optional Name parameter can be given in an attribute route, this can then be used when creating links to the route.
For example, when creating a resource with HTTP PUT, the response is often a CreatedAtRouteResult.
The CreatedAtRouteResult has two constructors, one taking a routeName string as first parameter, the other depends on the parameter routeValues to create a valid URI. Examples below are referring to the GetDroidById method shown in the routing constraint example below, the one defined to show using int as a constraint,
Creating a CreatedAtRouteResult using the Name parameter defined on a route:

new CreatedAtRouteResult("GetDroidById", new { id = droid.Id }, droid);

Creating a CreatedAtRouteResult using the values in the routeValues to construct the URI:

new CreatedAtRouteResult(new { Controller = "droids", Action = nameof(GetById), id = droid.Id }, droid)

Personally I’d avoid using the Name parameter as it only leads to usage of “magic strings”, it’s just to easy to miss these when refactoring methods in the API.

The Order Parameter

When using HTTP Method overloads, it’s important to keep track of in which order the endpoints will be executed. There is a definite ordering of routes that are dependent on literals, parameters, constraints and also the Order parameter. The ordering happens as follows:
1 – A comparison of the Order parameter.
2 – Literal segments.
3 – Route parameters with constraints.
4 – Route parameters without constraints.
5 – Wildcard parameter segments with constraints.
6 – Wildcard parameter segments without constraints.

Note! Do note that the usage of the Order parameter is based on comparison between different attribute signatures – meaning that if you only define the Order parameter on one route there will be no comparison against the other routes and the rest of the rules will define the inter-mutual ordering.

Routing Constraints

In the ASP.NET Core 1.0 Web API implementation, there is currently 17 different route constraints available. They could be more or less be divided in a few groups, being Type Based Constraints, String Length Constraints, Value Constraints and Regex-based Constraints.

We’ll take a look at all the constraints available in the ASP.NET Core Web API later, but first let’s look at how to use the route constraints.

Using Route Constraints

Using the constraints is done by adding a colon after parameters and then adding the specific constraint. An example of how to make the droid id only accept guid‘s as id’s:
/droids/{id:guid}/services/

Constraints taking values are specified by entering the value in a parentheses after the constraint. Here’s an example specifying that the droid id is a string that is not shorter than three chars:
/droids/{id:minlength(3)}/services/

It’s also possible to specify multiple restraints on a parameter, this is done by just adding another colon and another constraint. This example specifies that a droid’s id is an int and has a minimum value of five:
/droids/{id:int:min(3)}/services/

Type Based Constraints

There is eight different constraints used for specifying what type is expected, let’s take a look at them.
But first let’s call the droids controller without any parameters, it will list all the droids in the repository. This way you know what the data looks like and know what to expect when we start running the constraint examples below.

Calling the Web API can be done with several different tools.
My preferred method is to use Postman. I use Postman because it’s a great tool and because it enables me to save my requests, so I can work from multiple computers.

Call ASP.NET Core Web API from Postman

Using Postman to call the Web API

Another quick and easy test tool is to use the Invoke-RestMethod command from PowerShell.
Calling the GetAll base route from PowerShell would look like this:
Invoke-RestMethod http://localhost:5000/api/droids/
The result looks like this:

Using PowerShell to call an ASP.NET Core Web API

Calling our ASP.NET Core Web API from PowerShell

To transform the result-set in PowerShell to JSon, pipe the call through ConvertTo-Json, like this:
Invoke-RestMethod http://localhost:5000/api/droids/ | ConvertTo-Json
Note! A small tip, if you need to copy and paste the PowerShell result somewhere – Just append a “| clip” to the end and the result will be in your clipboard!

This is what the response looks like when piped through ConvertTo-Json in PowerShell:

{
    [
                  {
                      "id":  0,
                      "imperialContractId":  "0b450fdd-f484-423b-8685-4193e9fa583d",
                      "entryDate":  "2016-07-05T14:09:39.3426236Z",
                      "name":  "IG-88",
                      "creditBalance":  4611686018427387903,
                      "productSeries":  "IG-86",
                      "height":  1.96,
                      "armaments":  [
                                        "DAS-430 Neural Inhibitor",
                                        "Heavy pulse cannon",
                                        "Poison darts",
                                        "Toxic gas dispensers",
                                        "Vibroblades"
                                    ],
                      "equipment":  [

                                    ]
                  },
                  {
                      "id":  1,
                      "imperialContractId":  "00000000-0000-0000-0000-000000000000",
                      "entryDate":  "2016-07-05T14:09:39.3426236Z",
                      "name":  "C-3PO",
                      "creditBalance":  0,
                      "productSeries":  "3PO-series Protocol Droid",
                      "height":  1.71,
                      "armaments":  [

                                    ],
                      "equipment":  [
                                        "TranLang III communication module"
                                    ]
                  },
                  {
                      "id":  2,
                      "imperialContractId":  "00000000-0000-0000-0000-000000000000",
                      "entryDate":  "2016-07-05T14:09:39.3426236Z",
                      "name":  "R2-D2",
                      "creditBalance":  0,
                      "productSeries":  "R-Series",
                      "height":  0.96,
                      "armaments":  [
                                        "Buzz saw",
                                        "Electric pike"
                                    ],
                      "equipment":  [
                                        "Drinks tray (only on sail barge)",
                                        "Fusion welder",
                                        "Com link",
                                        "Power recharge coupler",
                                        "Rocket boosters",
                                        "Holographic projector/recorder",
                                        "Motorized, all-terrain treads",
                                        "Retractable third leg",
                                        "Periscope",
                                        "Fire extinguisher",
                                        "Hidden lightsaber compartment with ejector",
                                        "Data probe",
                                        "Life-form scanner",
                                        "Utility arm"
                                    ]
                  }
              ]
}

The above dataset is what we’re going to use for all examples below that use the DroidsController (to get the code, see the last section of this post).

Now, let’s get on with the Route Constraint examples. They are presented in a brief summary, then the code to implement it in the Web API and then finally the result when calling the endpoint in PowerShell.

Int Route Constraint

Below an example of using the int constraint, using it to specify a droid id.

        /// <summary>
        /// Int as constraint
        /// </summary>
        /// <param name="id">droid id</param>
        /// <returns>A droid with a specific Id</returns>
        [HttpGet("{id:int}", Name = "GetDroidById", Order = 0)]
        public IActionResult GetById(int id)
        {
            var droid = droidRepo.Get(id);

            if (droid == null)
            {
                return new NotFoundObjectResult(
                    new Error.Repository.Error
                    {
                        HttpCode = 404,
                        Message = $"Droid with id: {id} - Not found in database!"
                    }
                );
            }

            return new OkObjectResult(droid);
        }

Calling the route from PowerShell like this:
Invoke-RestMethod http://localhost:5000/api/droids/0 | ConvertTo-Json
Gives the response:

{
    "id":  0,
    "imperialContractId":  "0b450fdd-f484-423b-8685-4193e9fa583d",
    "entryDate":  "2016-07-05T14:02:03.1161577Z",
    "name":  "IG-88",
    "creditBalance":  4611686018427387903,
    "productSeries":  "IG-86",
    "height":  1.96,
    "armaments":  [
                      "DAS-430 Neural Inhibitor",
                      "Heavy pulse cannon",
                      "Poison darts",
                      "Toxic gas dispensers",
                      "Vibroblades"
                  ],
    "equipment":  [

                  ]
}

Bool Route Constraint

Here’s an example of using the bool constraint, toggling if the droids armaments should be included in the response.

        /// <summary>
        /// Bool as constraint
        /// </summary>
        /// <param name="withWeapons">toggle armaments</param>
        /// <returns>A droid with or without armaments</returns>
        [HttpGet("{withWeapons:bool}")]
        public IActionResult GetWithArmaments(bool withWeapons)
        {
            var droids = droidRepo.GetAll();
            if (droids == null)
            {
                return new NotFoundObjectResult(
                    new Error.Repository.Error
                    {
                        HttpCode = 404,
                        Message = $"No Droids found in database!"
                    }
                );
            }

            if (!withWeapons)
            {
                foreach (var droid in droids)
                {
                    droid.Armaments = Enumerable.Empty<string>();
                }
            }
            return new OkObjectResult(droids);
        }

Calling the route from Powershell like this:
Invoke-RestMethod http://localhost:5000/api/droids/false | ConvertTo-Json
Gives the response:

{
   [
                  {
                      "id":  0,
                      "imperialContractId":  "0b450fdd-f484-423b-8685-4193e9fa583d",
                      "entryDate":  "2016-07-05T15:09:10.9743745Z",
                      "name":  "IG-88",
                      "creditBalance":  4611686018427387903,
                      "productSeries":  "IG-86",
                      "height":  1.96,
                      "armaments":  [

                                    ],
                      "equipment":  [

                                    ]
                  },
                  {
                      "id":  1,
                      "imperialContractId":  "00000000-0000-0000-0000-000000000000",
                      "entryDate":  "2016-07-05T15:09:10.9743745Z",
                      "name":  "C-3PO",
                      "creditBalance":  0,
                      "productSeries":  "3PO-series Protocol Droid",
                      "height":  1.71,
                      "armaments":  [

                                    ],
                      "equipment":  [
                                        "TranLang III communication module"
                                    ]
                  },
                  {
                      "id":  2,
                      "imperialContractId":  "00000000-0000-0000-0000-000000000000",
                      "entryDate":  "2016-07-05T15:09:10.9743745Z",
                      "name":  "R2-D2",
                      "creditBalance":  0,
                      "productSeries":  "R-Series",
                      "height":  0.96,
                      "armaments":  [

                                    ],
                      "equipment":  [
                                        "Drinks tray (only on sail barge)",
                                        "Fusion welder",
                                        "Com link",
                                        "Power recharge coupler",
                                        "Rocket boosters",
                                        "Holographic projector/recorder",
                                        "Motorized, all-terrain treads",
                                        "Retractable third leg",
                                        "Periscope",
                                        "Fire extinguisher",
                                        "Hidden lightsaber compartment with ejector",
                                        "Data probe",
                                        "Life-form scanner",
                                        "Utility arm"
                                    ]
                  }
              ]
}

DateTime Route Constraint

This is an example of using the DateTime route constraint, here we are using it to specify how old an droid entry can be for it to be included in the response.

        /// <summary>
        /// DateTime as a constraint
        /// </summary>
        /// <param name="entryDate">date of registration in the galactic registry</param>
        /// <returns>all droids registered in the galactic registry after a specified date</returns>
        [HttpGet("{entryDate:datetime}")]
        public IActionResult GetByEntryDate(DateTime entryDate)
        {
            var droids = droidRepo.GetAllFromEntryDate(entryDate);
            if (droids == null || droids?.Count() == 0)
            {
                return new NotFoundObjectResult(
                    new Error.Repository.Error
                    {
                        HttpCode = 404,
                        Message = $"No Droids found in database created after {entryDate}!"
                    }
                );
            }
            return new OkObjectResult(droids);
        }

Calling the route from Powershell like this:
Invoke-RestMethod http://localhost:5000/api/droids/2016-07-04 | ConvertTo-Json
Gives the response:

{
    [
                  {
                      "id":  1,
                      "imperialContractId":  "00000000-0000-0000-0000-000000000000",
                      "entryDate":  "2016-07-05T14:02:03.1171574Z",
                      "name":  "C-3PO",
                      "creditBalance":  0,
                      "productSeries":  "3PO-series Protocol Droid",
                      "height":  1.71,
                      "armaments":  [

                                    ],
                      "equipment":  [
                                        "TranLang III communication module"
                                    ]
                  },
                  {
                      "id":  0,
                      "imperialContractId":  "0b450fdd-f484-423b-8685-4193e9fa583d",
                      "entryDate":  "2016-07-05T14:02:03.1161577Z",
                      "name":  "IG-88",
                      "creditBalance":  4611686018427387903,
                      "productSeries":  "IG-86",
                      "height":  1.96,
                      "armaments":  [
                                        "DAS-430 Neural Inhibitor",
                                        "Heavy pulse cannon",
                                        "Poison darts",
                                        "Toxic gas dispensers",
                                        "Vibroblades"
                                    ],
                      "equipment":  [

                                    ]
                  },
                  {
                      "id":  2,
                      "imperialContractId":  "00000000-0000-0000-0000-000000000000",
                      "entryDate":  "2016-07-05T14:02:03.1171574Z",
                      "name":  "R2-D2",
                      "creditBalance":  0,
                      "productSeries":  "R-Series",
                      "height":  0.96,
                      "armaments":  [
                                        "Buzz saw",
                                        "Electric pike"
                                    ],
                      "equipment":  [
                                        "Drinks tray (only on sail barge)",
                                        "Fusion welder",
                                        "Com link",
                                        "Power recharge coupler",
                                        "Rocket boosters",
                                        "Holographic projector/recorder",
                                        "Motorized, all-terrain treads",
                                        "Retractable third leg",
                                        "Periscope",
                                        "Fire extinguisher",
                                        "Hidden lightsaber compartment with ejector",
                                        "Data probe",
                                        "Life-form scanner",
                                        "Utility arm"
                                    ]
                  }
              ]
}

Decimal Route Constraint

This is an example of the decimal constraint, used to specify a minimum height of droids.

        /// <summary>
        /// Decimal as a constraint
        /// </summary>
        /// <param name="height">a given height</param>
        /// <returns>all droids over a given height</returns>
        [HttpGet("{height:decimal}", Order = 7)]
        public IActionResult GetByHeightDecimal(decimal height)
        {
            var droids = droidRepo.GetAllTallerThan(height);
            if (droids == null || droids?.Count() == 0)
            {
                return new NotFoundObjectResult(
                    new Error.Repository.Error
                    {
                        HttpCode = 404,
                        Message = $"No Droids found in database taller than {height}!"
                    }
                );
            }
            return new OkObjectResult(droids);
        }

Calling the route from Powershell like this:
Invoke-RestMethod http://localhost:5000/api/droids/1.90 | ConvertTo-Json
Gives the response:

{
    [
                  {
                      "id":  0,
                      "imperialContractId":  "0b450fdd-f484-423b-8685-4193e9fa583d",
                      "entryDate":  "2016-07-06T00:13:57.0333804Z",
                      "name":  "IG-88",
                      "creditBalance":  4611686018427387903,
                      "productSeries":  "IG-86",
                      "height":  1.96,
                      "armaments":  [
                                        "DAS-430 Neural Inhibitor",
                                        "Heavy pulse cannon",
                                        "Poison darts",
                                        "Toxic gas dispensers",
                                        "Vibroblades"
                                    ],
                      "equipment":  [

                                    ]
                  }
              ]
}

Double Route Constraint

The following example shows an overload of getting droid heights specified as a double.

        /// <summary>
        /// Double as a constraint
        /// </summary>
        /// <param name="height">a given height</param>
        /// <returns>all droids over a given height</returns>
        [HttpGet("{height:double}", Order = 3)]
        public IActionResult GetByHeightDouble(double height)
        {
            decimal convertedHeight = (decimal)height;
            var droids = droidRepo.GetAllTallerThan(convertedHeight);
            if (droids == null || droids?.Count() == 0)
            {
                return new NotFoundObjectResult(
                    new Error.Repository.Error
                    {
                        HttpCode = 404,
                        Message = $"No Droids found in database taller than {height}!"
                    }
                );
            }
            return new OkObjectResult(droids);
        }

Calling the route from Powershell like this:
Invoke-RestMethod http://localhost:5000/api/droids/100E-2 | ConvertTo-Json
Gives the response:

{
    [
                  {
                      "id":  1,
                      "imperialContractId":  "00000000-0000-0000-0000-000000000000",
                      "entryDate":  "2016-07-06T00:13:57.0343798Z",
                      "name":  "C-3PO",
                      "creditBalance":  0,
                      "productSeries":  "3PO-series Protocol Droid",
                      "height":  1.71,
                      "armaments":  [

                                    ],
                      "equipment":  [
                                        "TranLang III communication module"
                                    ]
                  },
                  {
                      "id":  0,
                      "imperialContractId":  "0b450fdd-f484-423b-8685-4193e9fa583d",
                      "entryDate":  "2016-07-06T00:13:57.0333804Z",
                      "name":  "IG-88",
                      "creditBalance":  4611686018427387903,
                      "productSeries":  "IG-86",
                      "height":  1.96,
                      "armaments":  [
                                        "DAS-430 Neural Inhibitor",
                                        "Heavy pulse cannon",
                                        "Poison darts",
                                        "Toxic gas dispensers",
                                        "Vibroblades"
                                    ],
                      "equipment":  [

                                    ]
                  }
              ]
}

Float Route Constraint

And another overload for getting droid height using a float. (Yeah, running out of good examples here, I know πŸ™ )

        /// <summary>
        /// Float as a constraint
        /// </summary>
        /// <param name="height">a given height</param>
        /// <returns>all droids over a given height</returns>
        [HttpGet("{height:float}", Order = 4)]
        public IActionResult GetByHeightFloat(float height)
        {
            decimal convertedHeight = (decimal)height;
            var droids = droidRepo.GetAllTallerThan(convertedHeight);
            if (droids == null || droids?.Count() == 0)
            {
                return new NotFoundObjectResult(
                    new Error.Repository.Error
                    {
                        HttpCode = 404,
                        Message = $"No Droids found in database taller than {height}!"
                    }
                );
            }
            return new OkObjectResult(droids);
        }

Calling the route from Powershell like this:
Invoke-RestMethod http://localhost:5000/api/droids/0.95 | ConvertTo-Json
Gives the response:

[
    {
        "id":  0,
        "imperialContractId":  "0b450fdd-f484-423b-8685-4193e9fa583d",
        "entryDate":  "2016-07-06T00:26:27.6872656Z",
        "name":  "IG-88",
        "creditBalance":  4611686018427387903,
        "productSeries":  "IG-86",
        "height":  1.96,
        "armaments":  [
                          "DAS-430 Neural Inhibitor",
                          "Heavy pulse cannon",
                          "Poison darts",
                          "Toxic gas dispensers",
                          "Vibroblades"
                      ],
        "equipment":  [

                      ]
    },
    {
        "id":  1,
        "imperialContractId":  "00000000-0000-0000-0000-000000000000",
        "entryDate":  "2016-07-06T00:26:27.6882653Z",
        "name":  "C-3PO",
        "creditBalance":  0,
        "productSeries":  "3PO-series Protocol Droid",
        "height":  1.71,
        "armaments":  [

                      ],
        "equipment":  [
                          "TranLang III communication module"
                      ]
    },
    {
        "id":  2,
        "imperialContractId":  "00000000-0000-0000-0000-000000000000",
        "entryDate":  "2016-07-06T00:26:27.6882653Z",
        "name":  "R2-D2",
        "creditBalance":  0,
        "productSeries":  "R-Series",
        "height":  0.96,
        "armaments":  [
                          "Buzz saw",
                          "Electric pike"
                      ],
        "equipment":  [
                          "Drinks tray (only on sail barge)",
                          "Fusion welder",
                          "Com link",
                          "Power recharge coupler",
                          "Rocket boosters",
                          "Holographic projector/recorder",
                          "Motorized, all-terrain treads",
                          "Retractable third leg",
                          "Periscope",
                          "Fire extinguisher",
                          "Hidden lightsaber compartment with ejector",
                          "Data probe",
                          "Life-form scanner",
                          "Utility arm"
                      ]
    }
]

Note! Make sure you get your Order parameters correct if you are implementing endpoints that take float, double and decimal in the same Controller!

Guid Route Constraint

Here’s a route for getting droids by their imperial contract id, and they are of course specified with guid’s.

        /// <summary>
        /// Guid as a constraint
        /// </summary>
        /// <param name="contractId">imperial contract id</param>
        /// <returns>an eventual droid matching given contract id</returns>
        [HttpGet("{contractId:guid}")]
        public IActionResult GetByImperialContractId(Guid contractId)
        {
            var droid = droidRepo.GetByImperialId(contractId);
            if (droid == null)
            {
                return new NotFoundObjectResult(
                    new Error.Repository.Error
                    {
                        HttpCode = 404,
                        Message = $"No Droid found in database with a imperial contract id of {contractId}!"
                    }
                );
            }
            return new OkObjectResult(droid);
        }

Calling the route from Powershell like this:
Invoke-RestMethod http://localhost:5000/api/droids/0B450FDD-F484-423B-8685-4193E9FA583D | ConvertTo-Json
Gives the response:

{
    "id":  0,
    "imperialContractId":  "0b450fdd-f484-423b-8685-4193e9fa583d",
    "entryDate":  "2016-07-06T00:26:27.6872656Z",
    "name":  "IG-88",
    "creditBalance":  4611686018427387903,
    "productSeries":  "IG-86",
    "height":  1.96,
    "armaments":  [
                      "DAS-430 Neural Inhibitor",
                      "Heavy pulse cannon",
                      "Poison darts",
                      "Toxic gas dispensers",
                      "Vibroblades"
                  ],
    "equipment":  [

                  ]
}

Long Route Constraint

What’s the fun of being a bounty hunting droid if you don’t see that credit balance increase?
Here’s a route to fetch the credit balance for a droid, using the long route constraint.

        /// <summary>
        /// Long as a constraint
        /// </summary>
        /// <param name="creditBalance">an credit limit</param>
        /// <returns>any droid with a given credit balance over given limit</returns>
        [HttpGet("{creditBalance:long}", Order = 0)]
        public IActionResult GetByCreditBalance(long creditBalance)
        {
            IEnumerable<Droid> droids = droidRepo.GetByCreditBalance(creditBalance);
            if (droids == null || droids?.Count() == 0)
            {
                return new NotFoundObjectResult(
                    new Error.Repository.Error
                    {
                        HttpCode = 404,
                        Message = $"No Droid found in database with a credit balance over {creditBalance}!"
                    }
                );
            }
            return new OkObjectResult(droids);
        }

Calling the route from PowerShell like this:
Invoke-RestMethod http://localhost:5000/api/droids/461168601842738790 | ConvertTo-Json
Gives the response:

{
    "id":  0,
    "imperialContractId":  "0b450fdd-f484-423b-8685-4193e9fa583d",
    "entryDate":  "2016-07-06T00:26:27.6872656Z",
    "name":  "IG-88",
    "creditBalance":  4611686018427387903,
    "productSeries":  "IG-86",
    "height":  1.96,
    "armaments":  [
                      "DAS-430 Neural Inhibitor",
                      "Heavy pulse cannon",
                      "Poison darts",
                      "Toxic gas dispensers",
                      "Vibroblades"
                  ],
    "equipment":  [

                  ]
}

String Length Constraints

MinLength and MaxLength Route Constraint

In this example we are combining two route constraints. Both MinLength and MaxLength is used to specify an input between 2 to 4 characters that’s going to be used to search the specified droids armaments.

        /// <summary>
        /// Using a string with minlenght and maxlength to search for armaments
        /// </summary>
        /// <param name="droidId">droid id</param>
        /// <param name="armament">armament search string</param>
        /// <returns></returns>
        [HttpGet("{droidId:int}/{armament:minlength(2):maxlength(4)}")]
        public IActionResult GetSpecificArmament(int droidId, string armament)
        {
            var droid = droidRepo.Get(droidId);
            if (droid == null)
            {
                return new NotFoundObjectResult(
                    new Error.Repository.Error
                    {
                        HttpCode = 404,
                        Message = $"Droid with id: {droidId} - Not found in database!"
                    }
                );
            }

            var matchingArmaments = droid.Armaments.Where(a => a.Contains(armament));
            return new OkObjectResult(matchingArmaments);
        }

Calling the route from PowerShell like this:
Invoke-RestMethod http://localhost:5000/api/droids/0/gas | ConvertTo-Json
Gives the response:

"Toxic gas dispensers"

Length Route Constraint

For the route to search for a specific droid by name, we’re using the length route constraint to specify that a droids name can be 5 charachters long – no more and no less.

        /// <summary>
        /// String of a specific length used as a constraint
        /// </summary>
        /// <param name="name">droid name</param>
        /// <returns>an eventual droid matching the given name</returns>
        [HttpGet("{name:length(5)}")]
        public IActionResult Get(string name)
        {
            var droid = droidRepo.Get(name);
            if (droid == null)
            {
                return new NotFoundObjectResult(
                    new Error.Repository.Error
                    {
                        HttpCode = 404,
                        Message = $"{name} - No such Droid in database!"
                    }
                );
            }
            return new OkObjectResult(droidRepo.Get(name));
        }

Calling the route from PowerShell like this:
Invoke-RestMethod http://localhost:5000/api/droids/IG-88 | ConvertTo-Json
Gives the response:

{
    "id":  0,
    "imperialContractId":  "0b450fdd-f484-423b-8685-4193e9fa583d",
    "entryDate":  "2016-07-06T00:26:27.6872656Z",
    "name":  "IG-88",
    "creditBalance":  4611686018427387903,
    "productSeries":  "IG-86",
    "height":  1.96,
    "armaments":  [
                      "DAS-430 Neural Inhibitor",
                      "Heavy pulse cannon",
                      "Poison darts",
                      "Toxic gas dispensers",
                      "Vibroblades"
                  ],
    "equipment":  [

                  ]
}

Value Constraints

For the value constraints examples we have an endpoint that publishes a bunch of error descriptions. It has a range error codes matching internal errors, a range for external errors and a range for special errors.

Min Route Constraint

The min route constraint is used to specify the lower bounded value of the external errors range.

        /// <summary>
        /// min value specified for the constraint
        /// </summary>
        /// <param name="errorCode">error code to look for</param>
        /// <returns>an external error</returns>
        [HttpGet("{id:int:min(101)}", Order = 1)]
        public IActionResult GetExternalErrors(int errorCode)
        {
            var error = errorRepository.GetByErrorCode(errorCode);
            if (error == null)
            {
                return new BadRequestObjectResult(
                                    new Error.Repository.Error
                                    {
                                        ErrorCode = 0,
                                        HttpCode = 404,
                                        Message = $"No external Error with error code {errorCode} exists in the database!"
                                    });
            }
            return new OkObjectResult(error);
        }

Calling the route from PowerShell like this:
Invoke-RestMethod http://localhost:5000/api/errors/101 | ConvertTo-Json
Gives the response:

{
    "errorCode":  101,
    "httpCode":  404,
    "message":  "Too many fingers on keyboard error!"
}

Max Route Constraint

In this example a max value is set on the constraint to limit the range of the internal errors.

        /// <summary>
        /// max value specified for the contraint
        /// </summary>
        /// <param name="errorCode">error code to look for</param>
        /// <returns>an internal error</returns>
        [HttpGet("{id:int:max(100)}", Order = 2)]
        public IActionResult GetInternalErrors(int errorCode)
        {
            var error = errorRepository.GetByErrorCode(errorCode);
            if (error == null)
            {
                return new BadRequestObjectResult(
                                    new Error.Repository.Error
                                    {
                                        ErrorCode = 0,
                                        HttpCode = 404,
                                        Message = $"No internal Error with error code {errorCode} exists in the database!"
                                    });
            }
            return new OkObjectResult(error);
        }

Calling the route from Postman with a get and using this URL:
http://localhost:5000/api/errors/99
Gives the following response (however note that this isn’t copied from a PowerShell invoke, since it returns a 400 – PowerShell refuses to produce proper output). Instead the response as taken from Postman looks like this:

{
  "errorCode": 99,
  "httpCode": 404,
  "message": "No internal Error with error code 99 exists in the database!"
}

Range Route Constraint

And for the final value constraint we’re using the range keyword to specify a range of values available for special errors.

        /// <summary>
        /// range of values specified on the constraint
        /// </summary>
        /// <param name="errorCode">error code to look for</param>
        /// <returns>a special error</returns>
        [HttpGet("{id:int:range(665,667)}", Order = 0)]
        public IActionResult GetSpecialErrors(int errorCode)
        {
            var error = errorRepository.GetByErrorCode(errorCode);
            if (error == null)
            {
                return new BadRequestObjectResult(
                                    new Error.Repository.Error
                                    {
                                        ErrorCode = errorCode,
                                        HttpCode = 404,
                                        Message = $"No special Error with error code {errorCode} exists in the database!"
                                    });
            }
            return new OkObjectResult(error);
        }

Calling the route from Postman with a get and using this URL:
http://localhost:5000/api/errors/665
Gives the response:

{
  "errorCode": 665,
  "httpCode": 404,
  "message": "No special Error with error code 665 exists in the database!"
}

String Matching Constraints

Two constraints are string matching/regex based, these are the Alpha and the Regex constraints.
To demo them we have a simple Users controller, serving info about users of a system.

Alpha Route Constraint

The alpha constraint requires the letters a-z & A-Z.

        /// <summary>
        /// Alpha as a constraint
        /// </summary>
        /// <param name="handle">a users handle</param>
        /// <returns>a user with the given handle</returns>
        [HttpGet("{handle:alpha}", Order = 1)]
        public IActionResult GetByHandle(string handle)
        {
            var user = usersRepository.GetUserByHandle(handle);
            if (user == null)
            {
                return new BadRequestObjectResult(
                                    new Error.Repository.Error
                                    {
                                        ErrorCode = 201,
                                        HttpCode = 404,
                                        Message = $"No User with handle {handle} exists in the database!"
                                    });
            }
            return new OkObjectResult(user);
        }

Calling the route from PowerShell like this:
Invoke-RestMethod http://localhost:5000/users/mobilemancer/ | ConvertTo-Json
Gives the response:

{
    "handle":  "mobilemancer",
    "id":  0,
    "firstName":  "Andreas",
    "lastName":  "W?nqvist",
    "email":  "fake@mobilemancer.com"
}

Regex Route Constraint

This example is showing a practice of something that should never be done, sending personal information in the URL!
But as it’s just an example, here is a route with a very simple regex constraint that’s checking the format of the incoming parameter and making sure it resembles an email address.

        /// <summary>
        /// Regex as a constraint
        /// </summary>
        /// <param name="email">a users email address</param>
        /// <returns>a user with the given email address</returns>
        [HttpGet("{email:regex(^\\S+@\\S+$)}", Order = 2)]
        public IActionResult GetByEmail(string email)
        {
            var user = usersRepository.GetUserByEmail(email);
            if (user == null)
            {
                return new BadRequestObjectResult(
                                    new Error.Repository.Error
                                    {
                                        ErrorCode = 202,
                                        HttpCode = 404,
                                        Message = $"No User with email {email} exists in the database!"
                                    });
            }
            return new OkObjectResult(user);
        }

Calling the route from PowerShell like this:
Invoke-RestMethod http://localhost:5000/users/fake@mobilemancer.com | ConvertTo-Json
Gives the response:

{
    "handle":  "mobilemancer",
    "id":  0,
    "firstName":  "Andreas",
    "lastName":  "W?nqvist",
    "email":  "fake@mobilemancer.com"
}

Required Route Constraint

This constraint is supposedly used to mark any parameter in a route to be required. But I can’t think of any good example πŸ™
If you can come up with a good example, let me know in the comments and it’ll end up here together with links to your twitter, blog or LinkedIn profile – whatever you prefer! πŸ™‚

Get the Code

Checkout my GitHub repository if you want to take a closer look at any of the code used for this post, you can find it under the Core-WebAPI repo.

Happy Coding! πŸ™‚


More ASP.NET Core Posts

How to create a Web API on ASP.NET Core with a minimal amount of code – Minimal Web API on ASP.NET Core
Quick setup of SSL for local dev with ASP.NET Core – ASP.Net Core – IIS Express and SSL

post image

Minimal Web API on ASP.NET Core

How to setup a minimal Web API in ASP.NET Core

Feel like playing around with the new .NET Core bits? Do you wonder how little code is needed to setup a Web API on .NET Core? Then this post is right up your alley!

Prerequisites

The .NET Core bits(dot.net), Visual Studio Code (code.visualstudio.com), but any editor will do

Setup

The plan is to create a new project with the help of the new .NET Core tools. Then add just enough dependencies and code to get a basic Web API up and running.

Creating the Web API

  1. Create a folder for the project and position in the folder in your favorite CLI
  2. Type “dotnet new” to create a basic project
  3. Type “code .” to open up Visual Studio Code
  4. Add the following to the dependencies section in project.json
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final"
    
  5. Run a package restore with “dotnet restore”
  6. Open Program.cs and add a using statement for “Microsoft.AspNetCore.Hosting”
  7. Modify the Main method in Program.cs it accordingly
     public static void Main(string[] args)
            {
                   var host = new WebHostBuilder()
                    .UseKestrel()
                    .UseStartup<Startup>()
                    .Build();
    
                host.Run();
            }
    
  8. Add a Startup.cs file in the root and edit it as follows
    using Microsoft.AspNetCore.Builder;
    using Microsoft.Extensions.DependencyInjection;
    
    namespace ConsoleApplication
    {
        public class Startup
        {
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc();
            }
    
            public void Configure(IApplicationBuilder app)
            {
                app.UseMvc();
            }
        }
    }
    
  9. Add a “Controllers” folder
  10. Add a GrettingController.cs file in the folder and add the following code
    using Microsoft.AspNetCore.Mvc;
    
    namespace ConsoleApplication
    {
        [Route("api/[controller]")]
        public class GreetingController
        {
            [HttpGet]
            public string Get()
            {
                return "Greetings from .NET Core Web API!";
            }
        }
    }
    
  11. Position in the root folder and build the project with “dotnet build”
  12. Run the project with “dotnet run”
  13. Open a browser and hit “http://localhost:5000/api/greeting”
  14. Given everything worked as planned, you’ll now see the merry greeting in your browser!

    Get the code

    The code is available on my GitHub account.

    Happy Coding! πŸ™‚

post image

Basic TypeScript on ASP.NET Core with Visual Studio 2015 in 5 steps

TypeScript and ASP.NET Core with Visual Studio 2015

With the new rc2 release of ASP.NET a lot happened with what we previously knew as ASP.NET 5. Not only did the naming of the framework change (ASP.NET 5 to ASP.NET Core), but also the tools we previously used for ASP.NET 5 got changed and renamed. In Visual Studio a few things changed as well, such as the templates and some tooling.

However, this post is not about to go into the details of all changes, but rather show how to get from first TypeScript file to executing it in the web browser as fast as possible.

OBS! For version disclaimer & project setup – see the bottom of the post

Aim of this post

If you want to start playing around with TypeScript and ASP.NET Core and want to get going as quickly as possible, this is the post for you. The purpose of the post is to show how to get TypeScript files transpiled to JavaScript and serve these and other static html files with ASP.NET Core.

Step 1 – Create New Project

First we need to create a new web project:
Select File -> New -> Project and then the ASP.NET Core Web Application.
Create a new ASP.NET Core Web APP

Then select the Empty template.
Select the Empty template

Step 2 – Add static file serving to the pipeline

In the newly created solution, open the Startup.cs file and replace the Configure method with the following code:

        public void Configure(IApplicationBuilder app)
        {
            app.UseDefaultFiles();
            app.UseStaticFiles();
        }

Add the missing dependency to Microsoft.AspNetCore.StatiFiles using the helpful light bulb (Ctrl + .).

Step 3 – Add an html file

Add an index.html file inside the wwwroot folder.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <h1>Hello TypeScript fans!</h1>
</body>
</html>

Step 4 – Add a TypeScript file and produce JavaScript

Add a TypeScript file (file.ts) and enter some simple code in it, for ex:

(() => { alert("Made with TypeScriptβ„’"); })();

Notice that the file get’s transpiled when you press save and the JavaScript file is saved in the same folder as the TypeScript file.
TypeScript file transpiles to JavaScript on save

Step 5 – Reference the JavaScript file

Add a reference to the JavaScript file in the html file created earlier, for ex in the header tag.

<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="file.js"></script>
</head>

Run the project

Start the project (Ctrl + F5) and a browser should open up, load the index.html file and pop the alert.

Version Disclaimer & Project Setup

The code for this post was written using Visual Studio 2015 Enterprise with Update 2, ASP.NET Core with runtime rc-2. The code was tested in Microsoft Edge.

Visual Studio had the following products installed:

  • ASP.NET and Web Tools 2015.1 14.1.20512.0
  • ASP.NET Web Frameworks and Tools 2012.2 4.1.41102.0
  • ASP.NET Web Frameworks and Tools 2013 5.2.40314.0
  • Microsoft .NET Core Tools (Preview 1) 14.1.20512.0
  • TypeScript 1.8.31.0

Happy coding! πŸ™‚

post image

Aurelia – TypeScript – ASP.NET 5 – VS Code

Get started with Aurelia – TypeScript – ASP.NET 5 – VS Code

A while ago I wrote a blog post about how to get up and running with the Aurelia skeleton for TypeScript on ASP.NET 5 (This Aurelia Skeleton on ASP.NET 5). But now the Aurelia team now have their own setup, making it even easier to get started! πŸ™‚

Pre-Requisites

Things that need to be installed on your system:

  • ASP.NET 5
  • Node

Node packages that needs to be installed globally:

  • gulp
  • jspm

Get the code

Go to the Aurelia skeleton repo on GitHub
Download as zip, use GitHub for Desktop or whatever you prefer.

Install dependencies

Open a cmd prompt in the project root and install the project dependencies with:

  • npm install
  • jspm install

Build the code

In the cmd prompt, use the following to build the client side code:
gulp build

Then open VS Code and open the folder skeleton-navigation\skeleton-typescript-asp.net5\src
VS Code will the prompt and ask to restore missing packages, accept this request.

Now start the ASP.NET 5 host by typing the following in the cmd prompt:
dnx web

Now open a browser and go to http://localhost:9000, if everything has worked, you should see the Aurelia navigation skeleton!



Happy coding πŸ™‚

ASP.NET Core – IIS Express and SSL

Setting up SSL on a dev machine running self hosting

After a lot of yak shaving this is what I found to be the easiest way to set up my dev machine(Win10) using SSL for ASP.NET Core development.

Prerequisites

IIS Express needs to be installed on your machine already. Since the whole idea is to borrow the cert it uses. If not, use makecert and create your own certificate.

Steps to success

Follow the steps below to use the IIS Express certificate to enable SSL against localhost.

1. Get the cert Hash and App ID

An easy way to get the Hash and App ID of the cert is to list all http bindings in a file, just open a CLI and enter the following:
netsh http show sslcert > output.txt
This will list all the bindings in the file named output.txt, the IIS Express cert is the one registered on port 44300 and above.

Make note of the Hash and App ID.
Certificate Bindings port 44300 IIS Express

2. Add SSL for a selected port

Add the cert for our selected port 5043 with:
netsh http add sslcert ipport=0.0.0.0:5043 appid={AppId} certhash=CertHash
Note, if you’re CLI of choice is PowerShell, you need to add single quotes around the curly bracers.
If everything goes well you’ll see:
“SSL Certificate successfully added”

3. Setting up project.json

Set the web command in project.json to:
“web”: “Microsoft.AspNet.Hosting –server Microsoft.AspNet.Server.WebListener –server.urls https://localhost:5043”
Make sure a dependency on “Microsoft.AspNet.Server.WebListener”: “1.0.0-rc1-final” is added, if not add it and run a “dnu restore”

Running “dnx web” should now start the server correctly and browsing https://localhost:5043 should be possible, although it will complain the connection is not private.
https dnx asp.net 5 asp.net core

Eventual issues

SSL Certificate add failed, Error: 1312
A specified logon session does not exist. It may already have been terminated.

If you end up with this problem when adding the ssl cert to the port, make sure the cert is in the Personal Certificates store. (Name of the cert is localhost)

The parameter is incorrect.

If you’re seeing this, chances is you are using PowerShell and and forgot single quotes around the angle brackets.

Happy coding πŸ™‚

post image

VS2015 Restore Packages Not Working Properly

Visual Studio 2015 – Don’t trust the package restore

I ran into a problem at work the other day, after a branch merge all icons disappeared in our webapp for me.

We recently introduced a new build step in SASS where we colorize our SVG-icons, so it wasn’t too hard to figure out what had changed. What caused it though was a whole other problem, as no other team member had the same problem as me.

After sprinkling some log prints in the SASS-function used to fix our icons, it was evident it wasn’t being run at all. Fun thing was, there were no errors reported during the build step either.

The automatic package restore

Visual Studio 2015 Unresponsive Pakage Restore bower_components

How I spend a third of my workday on release day…

After some head scratching I decided to check versions of the npm packages in use. It turned out that this was ‘des pudels kern’.
The version of gulp-sass was specified as v2.1.1 in the package.json file, but on disk I had v1.3.3. I was naively thinking that the package versions would be correct since Visual Studio does a ‘Package Restore’ when loading a solution.

Loading a solution and running package restore is what happens when you swap branch, which I had done several times when I ran in to this issue.

Npm Install

Behind the scenes the Package Restore step is running ‘npm install’. So question is, was it a problem with the npm tooling or a Visual Studio issue?

Whatever the reason, the important thing is to know that Visual Studio’s ‘npm install’ isn’t to be trusted. Always check your npm packages after having version dependencies updated from a merge or pull.

Effects of Package Restore

Personally I think that this “Package Restore” behavior needs to be changed. When running larger solutions containing several Web Projects you’ll end up with a npm install running for all projects in the Solution when you open it or change branch.

At work we got a fairly large Solution with about 10 projects in it, and just swapping branch takes 15 minutes for the package restore, often more as my VS2015 crashes mid operation every other time. And then it takes 15 minutes more for the package restore that happens when I have to start up the studio again and load the solution.

My work machine is a three year old laptop, but it has got an i7 and 8GB of ram. Still it totally bogs down when the package restore is being run. And as web development should be accessible to all, it’s unfair to require a new stationary machine just to have a sane working development flow.

Improving Package Restore

First of all, the Package Restore functionality should be an option in the Visual Studio web tooling. I’ve seen rumors it’s possible to turn it off by disabling all External Web Tooling under Options, but this seems very clunky and quite the opposite of what we really want.

Even better would be if Visual Studio checked all installed packages and saw if they already matched what was specified in package.json. ViΓ³la, no need for unnecessary restores!

Oh, and if any one on the VS Team get’s to read this, clicking the bower_components folder totally hangs my VS too!

In Closing

If you are having the same issues or just agree with the improvement suggestions, please help forward these concerns to the Visual Studio Web Tooling Team!

Happy Coding! πŸ™‚

PS. Yes, I have used the feedback tool in Visual Studio. Many times. With no response. DS.

post image

Aurelia Skeleton on ASP.NET 5

Running the Aurelia Skeleton app on ASP.NET 5

Aurelia TypeScript VS Visual Studio Code
On Dec 17:th Rob Eisenberg blogged about a new patch on for Aurelia. Performance, Bug Fixes and Documentation improvements. The thing that got me the most excited was the announcement that the Aurelia Navigation Skeleton had been improved for the TypeScript scenario and adapted to be run under VS Code!

The Aurelia Skeleton Nav project is a nice piece of code! Planned to be used in a production scenario, so it has all kinds of goodness setup, like a watch task, bundling, unit and integration tests.

But as I’m a Microsoft guy, it lacked one thing. A setup to be able to run it on ASP.NET 5 instead of node.

Get the Aurelia project

First off, download the project from Aurelia.io, you can get it here.

Setting up the project to run on ASP.NET 5

A few pre-requisites is needed to be able to run the project to start of with. Let’s first sort all the npm packages needed.

Installing npm packages

First off we need to install the npm packages.

As some of the packages need depend on node-gyp to be compiled, Python needs to be installed on your machine.
If you haven’t got Python installed, download and install it. Version 2.7.10 is the recommended install for node-gyp.
Node-gyp is also need a C++ compiler. If you are running Windows 10, install any version of Visual Studio 2015 that you have got access too and make sure the C++ packages are included in the install.
After installing Python set an environment variable named: GYP_MSVS_VERSION and set the value to: 2015.

Now make sure everything is installed properly by running npm install from the root of the project.

Install global npm dependencies>

The project is dependent on having a few packages installed globally as well, these being gulp and jspm.
To sort this, run the following:
npm install -g gulp
npm install -g jspm

Installing Aurelia with jspm

Now we need to install the Aurelia packages, and a few others. This is done by running the following form the root of the project:
jspm install

Make sure everything installed properly

Test the major part of the toolchain by building the project. Do this with:
gulp build

Setting up the ASP.NET 5 bits

If you are new to ASP.NET 5 and haven’t got the run-time installed, get it here.

First off we need to add two files, project.json and Startup.cs.
Mine looked like the following:

{
  "version": "1.0.0-*",
  "compilationOptions": {
    "emitEntryPoint": true
  },
  "tooling": {
    "defaultNamespace": "Aurelia_Skeleton"
  },

  "dependencies": {
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
    "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final"
  },

  "commands": {
    "web": "Microsoft.AspNet.Server.Kestrel"
  },

  "frameworks": {
    "dnx451": { },
    "dnxcore50": { }
  },

  "exclude": [
    "node_modules"
  ],
  "publishExclude": [
    "**.user",
    "**.vspscc"
  ]
}

and

using Microsoft.AspNet.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace Aurelia_Skeleton
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();            
            app.UseDefaultFiles();
            app.UseStaticFiles();
        }

        // Entry point for the application.
        public static void Main(string[] args) => Microsoft.AspNet.Hosting.WebApplication.Run<Startup>(args);
    }
}

After adding these files, go back to the command line and run the following:
dnu restore
dnu build

Given everything is installed correctly, the build should have gone ok and we can now start the web server with:
dnx web

Now everything should be installed, setup and ready to go, so just open a browser and hit http://localhost:5000 and the app should be loading!

Get the code

I forked the project and introduced my changes, you can get the code from my GitHub repository.

This was a quick setup and it’s not of production quality like the stuff from the Aurelia team, but it’s hopefully a start for those who want to play around with Aurelia on ASP.NET 5.

Happy Coding! πŸ™‚

post image

Running Tasks in Visual Studio Code

Running Tasks in VS Code

Time for another Coding Quick Tip – This time a look at running Tasks in Visual Studio Code. The content is available as a video at the end of the post if that’s what you prefer.

Setup

The test setup I got going is just a project with a few TypeScript files in them, and the task I’ll be rigging is just running the TypeScript compiler to transpile the code to JavaScript.

The prerequisites is that the Node and TypeScript compiler need to be installed. When Node is installed on the system, just type npm install -g typescript in a command window to install the TypeScript compiler as a global npm package. Verify that the compiler is properly installed by typing tsc -v

I also prefer to have config file for the TypeScript compiler, this can be created easily by entering tsc --init In the tsconfig.json file that will be created, I point out the location of the code and the directory where I wish the transpiled output to be placed.

Executing Commands

To run tasks from VS Code we need a configure the Task Runner. This is done by entering the Command Palette (F1 or ctrl-shift-p), typing task and selecting Tasks: Configure Task Runner.

VS Code Configure Task Runner Visual Studio Code

Configure the Task Runner in VS Code

This will create a tasks.json file under the .vscode directory in the current folder.
In the tasks.json file, edit the top-most example and remove the args parameter, as this is not needed when we got our tsconfig file setup.

Execute the task by opening the command palette, press backspace to remove the chevron and type task. This will show a drop down with all available tasks, right now just the one we recently created – named tsc.

VS Code Executing Task Visual Studio Code

Executing a task in Visual Studio Code

Running the task will compile our TypeScript files. Task accomplished (pun intended) – let’s move on.

Using a Task Runner

What if we want to use a task runner?
We’re in luck here if we like Jake, Grunt or Gulp as VS Code supports these out of the box. For this example I’m using Gulp.

First off, remove tasks.json so that we can start fresh.
After that, create a gulpfile.js in the folder with the select tasks defined (the one I’m using is listed below).

var gulp = require('gulp'),
    ts = require('gulp-typescript'),
    merge = require('merge'),
    fs = require("fs");

var webroot = "wwwroot";

var paths = {
    npm: './node_modules/',
    lib: "./" + webroot + "/lib/",
    tsSource: './TypeScript/**/*.ts',
    tsOutput: "./" + webroot + '/scripts/',
    tsDef: "./typings/internal/"
};

var tsCompilerConfig = ts.createProject('tsconfig.json');

gulp.task('ts-compile', function () {
    var tsResult = gulp.src(paths.tsSource)
        .pipe(ts(tsCompilerConfig));

    return merge([
        tsResult.dts.pipe(gulp.dest(paths.tsDef)),
        tsResult.js.pipe(gulp.dest(paths.tsOutput))
    ]);
});

gulp.task('watch', ['ts-compile'], function () {
    gulp.watch(paths.tsSource, ['ts-compile']);
});

Note, if you by any chance actually want to use the above gulp file, you need to install gulp, gulp-typescript and merge.
npm install gulp
npm install gulp-typescript
npm install merge?

Now we’re off to actually running the task again.
Open the Command Palette and type task, then select Tasks: Configure Task Runner, as in the first example.

Given all the used packages are installed correctly, a new tasks.json file will be created and look like the following

{
    "version": "0.1.0",
    "command": "gulp",
    "isShellCommand": true,
    "args": [
        "--no-color"
    ],
    "tasks": []
} 

You can now execute your Gulp tasks just like we executed our task in the example above.

Binding a task to VS Code’s “Run Build Task”

Visual Studio code has a command named Run Build Task, with the keybinding Ctrl+Shift+B. To improve the workflow in VS Code, this is the command to bind your build tasks too.
Binding the build task to the build command is done by setting the property isBuildTask to true for a specific task in the tasks.json file.

Let’s add our build task to tasks.json and try it out, modify tasks.josn like this:

{
    "version": "0.1.0",
    "command": "gulp",
    "isShellCommand": true,
    "args": [
        "--no-color"
    ],
    "tasks": [
        {
            "taskName": "ts-compile",
            "isBuildCommand": true
        }
    ]
}

Now execute the the task by pressing Ctrl+Shift+B, watch your bound task being run and rejoice πŸ™‚

That’s all for this Coding Quick Tip,
Happy Coding! πŸ™‚



post image

Get Started With ASP.NET 5 & VS Code – Video

Coding Quick Tip: Get Started With ASP.NET 5 and VS Code

I have been thinking of starting a series of quick tips in video format and here is the first episode. This time just showing how to get started developing in VS Code and scaffolding out an ASP.NET 5 project using Yeoman.

This was fun but it’s my first video so it’s definately a learning experience. It seems so easy when you look at all other good YouTube videos and now seeing my own result just makes me laugh. But what better way to learn than to do it in the open, feel some preassure and also be able to get some tips and critique? πŸ™‚

I know mic volume is really low, I need to fix that for my next vid. Maybe it’s even time to get a proper mic. Asking the misses for a x-mas gift just got easier I think πŸ˜€

I hope you enjoy the video even though it’s bad quality, low sound, mumbling and thought pauses. Please leave feedback if you got time!



Happy Coding! πŸ™‚

post image

TypeScript Classes Part III

TypeScript Classes Part III

Welcome to this second tutorial in the series covering classes in TypeScript. The topics covered in this episode is listed below.
TypeScript Classes Tutorial How-To Inheritance Interface Abstract Class

TypeScript Classes Part I – A New Hope (For structured JavaScript)

  1. Classes
  2. Constructors
  3. Scope Modifiers
  4. Parameter Shorthand

TypeScript Classes Part II – C# Strikes Back

  1. Accessors
  2. Static Properties

TypeScript Classes Part III – Return of the Object Hierarchy

  1. Inheritance
  2. Interfaces
  3. Abstract Classes

OBS! For version disclaimer & project setup – see the bottom of the post

Object Heirarchy

In this third episode we’re entering classical OO territory. Handling classes was, except for strong typing, the big thing that made TypeScript stand out compared to JavaScript when it was released.

Now classes are in the ES6 specs and thus coming to JavaScript, landing in a browser near you soon. But classes in JavaScript have been heavily debated in the community, and are still a divider for the passionate.

All class decisions haven’t been all uncontroversial in TypeScript either, Abstract Classes was the latest discussion point when being introduced in TypeScript 1.6.

For those of us coming from a more classic OO language before heading in to the JavaScript world, TypeScript and it’s classes can definitely be a good gateway in to actually enjoying a development environment that some developers fear, just because it’s lack of strong typing and non-straightforward OO patterns πŸ™‚

Inheritance

Class inheritance is denoted using the extends keyword. Just mark a class with extends and then the name of the class that should be inherited.

Notable, a class can only inherit from one base class.

Example code:

class Vehicle {
	private name: string;
	private speed: number;

	constructor(name: string, speed: number) {
		this.name = name;
		this.speed = speed;
	}

	move(distance: number): string {
		var time = distance / this.speed;
		return `${this.name} moved ${distance} kilometers in ${(time * 60).toFixed(2) } minutes`;
	}
}

Now we create a class which we wish to inherit from Vehicle and we do it using the extends keyword:

class AllTerrainVehicle extends Vehicle {
	private legs: number;

	constructor(name: string, speed: number, legs: number) {
		super(name, speed);
		this.legs = legs;
	}

	move(distance: number) {
		return super.move(distance) + ` by walking on ${this.legs} legs`;
	}
}

First thing to note is that a derived class always have to call the constructor of the base class. This is can be seen on row 5 in Example 2, and is done using super.

We can see the derived class only has one private member defined, but it actually has more state, as it has the members from the base class defined as well. And not only the members from the base class but also the methods defined.
Using methods from the base class is done with calling the method name on super. This can be seen on row 10 in Example 2, where the derived class uses a method from the base class and extends it’s functionality.

Interfaces

Interfaces are used to define contracts, telling the compiler that a class is expected to implement a set of members.

In contrast to class inheritance, a class can implement several interfaces at the same time.

In TypeScript interfaces are also used heavily to define the type structure for objects we need to work with. For ex, when retrieving data from a Web API, make sure to have an interface defined for it so it’s easier to work with in TypeScript.

Defining an interface is done with the interface keyword, let’s look at some code:

interface TroopCarrier {
	troopCapacity: number;
	medicalDroid: boolean;
	pickup(troops: number): string;
}

Here we see that any class that implements this interface must define three public members, two data members and one method. Mark that the name of the interface does not start with a capital i (I) as so often seen in other languages. If you are running a TypeScript linter it will surely complain about this, but according to Microsoft’s own guidelines, this practice is to be avoided.
Declaring that a class is adhering to a contract defined in an interface is done with the implements keyword. Let’s see an example:

class AllTerrainCarrierVehicle extends Vehicle implements TroopCarrier {
	private legs: number;
	private troopsInHold: number;

	troopCapacity: number;
	medicalDroid: boolean;

	constructor(name: string, speed: number, legs: number, troopCapacity: number, hasMedicalDroid: boolean) {
		super(name, speed);
		this.legs = legs;
		this.troopCapacity = troopCapacity;
		this.medicalDroid = hasMedicalDroid;
		this.troopsInHold = 0;
	}

	move(distance: number) {
		return super.move(distance) + ` by walking on ${this.legs} legs`;
	}

	pickup(troops: number): string {
		if (this.troopsInHold + troops > this.troopCapacity) {
			return "Can't pick up that many troops";
		} else {
			this.troopsInHold += troops;
			return "Troops picked up";
		}
	}
}

Notable is that interfaces only declare member signatures, ie. it’s not possible to have an interface specify any functionality. The TroopCarrier interface can thus only specify that the pickup method needs to be implemented and how the call signature for the method is supposed to look, but it can’t define any functionality for implementing classes to use.

Abstract Classes

Much alike Interfaces are Abstract Classes. In early TypeScript this construct wasn’t in the language spec, but since TypeScript 1.6 we now have access to Abstract Classes!

An abstract class is a class that can’t be used to instantiate any objects. So in that aspect it is much like an interface. However, an abstract class can define functionality that can be used from deriving classes.

Declaring an abstract class is done using the abstract keyword. Deriving from an abstract class is done with the extends keyword, just as inheritance from regular classes. Let’s look at an example:

abstract class RepulsorliftVehicle {
	private maxSpeed: number;
	private passengers: number;
	private armaments: string;

	constructor(maxSpeed: number, passengers: number, armaments?: string) {
		this.maxSpeed = maxSpeed;
		this.passengers = passengers;
		this.armaments = armaments;
	}

	abstract pickUpPassengers(noOfPassengers: number): string;

	fire(): string {
		if (!!this.armaments) {
			return `${this.armaments} fired!`;
		} else {
			return "No armaments to fire!";
		}
	}
}

Now if we try to new up an instance of RepulsorliftVehicle it won’t work. If we’re developing in an environment that supports TypeScript, we will get a warning saying the same as the compiler will. And running the compiler will yield the message:
TS2511: Cannot create an instance of the abstract class 'RepulsorliftVehicle'.
So what kind of JavaScript sorcery is this producing to employ such trickery? Actually nothing special, it’s just tooling working for us here πŸ™‚ If we look at the JavaScript produced it is just the same as all transpiled TypeScript classes.

Next up, inheriting from an abstract class, an example:

class SpeederBike extends RepulsorliftVehicle {
	constructor(maxSpeed: number, passengers: number, armaments: string) {
		super(maxSpeed, passengers, armaments);
	}

	pickUpPassengers(noOfPassengers: number): string {
		if (noOfPassengers > this.passengers) {
			return "Can't fit that many passengers";
		} else {
			return "Passenger get's on and holds on for dear life";
		}
	}
}

In the derived class we need to implement the methods declared as abstract in the base class, or the code won’t compile. Let’s test the SpeederBike and see what it can do:

var model74Z: SpeederBike = new SpeederBike(350, 1, "Ax-20 blaster cannon");
model74Z.pickUpPassengers(3); //returns Can't fit that many passengers
model74Z.pickUpPassengers(1); //returns Passenger get's on and holds on for dear life
model74Z.fire(); //returns Ax-20 blaster cannon fired!

Using the pickUpPassengers method that the base class had defined as abstract is done just as per usual. We also have access to the base class non abstract methods, calling fire on SpeederBike is ok.

So, that’s the strength of abstract classes demonstrated, the possibility to provide partial implementation of the behavior via the base class.

Conclusion

So this is the last part of the series detailing the workings of TypeScript classes. I hope that you have found it easy to follow along and get into the TypeScript way of handling OO. Good luck with your adventures in TypeScript and please leave a comment below, telling me how you TypeScript is workign out for you so far πŸ™‚

Version Disclaimer & Project Setup

The code for this post was written using Visual Studio Code, ASP.NET 5 (dnvm) with runtime rc-1. Node packages TypeScript v1.7.3 and gulp-typescript v2.9.2 were used. The project was setup to compile the TypeScript files with gulp. The code was tested in Microsoft Edge.

If you want to replicate this setup, just download the code from my GitHub repository here. If you want to read more about how to setup a TypeScript project in VS Code for ASP.NET 5, read this post.

Just starting out? Developing in TypeScript

Just a quick tip if you are new to TypeScript and need help getting started. I recommend either using Visual Studio Code or Visual Studio Community Edition. Both are free and excellent development tools. Which one you should select depends on your preferences.

VS Code is more of an editor, fast and light weight, but it won’t really hold your hand during learning. Now recently launched with extension support, with many great extensions already released and the Community working hard on many more πŸ™‚
Download Visual Studio Code.

Visual Studio is a full fledged IDE, it has pretty much everything you need to develop web, Windows applications, apps, etc. And if the functionality isn’t available out of the box, there’s a great extensibility API, enabling loads of excellent third party extensions, most of them free.
Download Visual Studio Community Edition.

More TypeScript posts for the curious

Tutorial on TypeScript Functions: TypeScript Functions

Setting up an Aurelia project in Visual Studio Code with TypeScript: Aurelia and TypeScript from VS Code

Tutorial for setting up a TypeScript – ASP.NET 5 app in VS2015: Getting started: TypeScript 1.5 in Visual Studio 2015

Tutorial for setting up a TypeScript – ASP.NET 5 app in Visual Studio Code: How-to: TypeScript in Visual Studio Code

Setup of a TypeScript – MVC 6 app that uses RequireJS in VS2015: Setting up a TypeScript – RequireJS – Gulp – MVC 6 Web Project in Visual Studio 2015 RC

Happy coding! πŸ™‚