ASP.NET Core Project with Angular 2, Aurelia and an API

I have been exploring Aurelia and more recently Angular 2 and while doing so I thought it might be nice to run both frameworks from the same project.  My first crack at this can be found in this repo on Github.

Content

  • Contact model, a simplified version of the one used in previous blogs
  • ContactsController and related razor views created using Visual Studio’s scaffolding tools based on the contact mode
  • ContactsApiController is the end point for the Angular 2 and Aurelia applications
  • Angular 2 application that closely match the one from last week’s post
  • Aurelia application is currently just a proof that Angular 2 and Aurelia could run in the same project. This application will be updated to connect to the project’s web API.

Getting Started

Ensure that node and jspm are install.

After acquiring the code open the solution. If using Visual Studio the npm based packages will be restored automatically. If not using Visual Studio then run   npm install from the console. This will handle all the files needed by Angular 2.

Next run the  jspm install -y  command to install the Aurelia related packages.

Make sure the database is created and up to date with the following two commands.

In wwwroot open the config.js file and verify the paths section looking like the following. Jspm install seems to rewrite the github and npm portions of the paths section which removed the “../”. This is more than likely a configuration issue that I hope to fix in the future.

Finally run the angular2 gulp task from the task runner. The application should now run with no issues.

First Run

Make sure to register a new user as both the contacts controllers require an authorized user and filter down the contacts to display based on the logged in user.

The menu bar will contain links for Angular 2, Aurelia and Razor. Use the razor link to create some data. This is the generated razor views mentioned above. It is also the only way to add data through the application currently.

The Angular 2 link will of course launch the Angular 2 application that will display a list of contacts for the current user.

The  Aurelia like will launch the Aurelia application which just contains the very basic application from the getting started guide.

Going Forward

The plan is to develop the Angular 2 and Aurelia applications together. The Aurelia application will be the first to get some time to get up to the same level as the Angular 2 application.

It is also my hope that having this project will be a good reference for you when reading the examples in future blog posts.

ASP.NET 5 Web API Put

As part of last week’s post on Aurelia’s Event Aggregator I needed a way to update existing contacts. This was a hole in my existing API and it was time to fill it.  See last week’s post for usage on the client side this post will only be covering the server side.

First off here is the code I added to the ContactsController in the API folder of my project. I thought the overview would be helpful a helpful context as we break down the different parts of the function.

First off the Update function is decorated to only handle HttpPut actions with an ID. The function itself of course requires an ID. The FormBody attribute on the updatedContact parameter tells the framework to build a contact object from the request body.

Next if the updatedContact was unable to be built from the request body or if the ID passed to the update function doesn’t match the ID in the updatedContact then a bad request status is returned.

Next I query the database for a matching contact. This query is limited to the current users so it should help prevent a contact for the wrong user being updated. If no matching contact is found then not found status is returned.

Next check to see if the mode state is valid and return bad request object result if it is not.

This next bit was a little bit of a challenge. Since entity framework was queried to see if the updated contact already exists I was getting an error when trying to use the DB context’s update function. One way to address this error would have been to update the contact pulled from the database with the values from the updated contact from the request body. If I had of gone this route something like automapper would have made the job fairly easy. Instead I used the DB context entry on the contact returned from the database to set its state to detached which tells the context to stop tracking that item. After that the context’s update function worked like a charm and I could save changes based on the updatedContact parameter.

Finally I returned the client the updated contact. This is the same thing I did for post and may or may not be the best thing to do on a put.

I am not sure how much of this is the “correct” way to handle a put. After seeing how some of this is handled when using razor with anti-forgery tokens and the ability to only allow certain fields to be updated this implementation seems lacking. This is a jumping off point, but I need to do more research on how to properly secure an API.

Migration from ASP.NET 5 Beta 8 to RC1

ASP.NET 5 release candidate 1 was released on November 18th. Read the announcement here.  The announcement happened during Connect where Microsoft talk about a ton of cool stuff. Hanselman did a great summary here.

One of the big things (for some people) is that with RC1 ASP.NET 5 now has a go live license which means Microsoft will provide support. One thing to note about the go live license is if a RC2 is released the support will immediately drop for RC1 and any application will need to be upgraded to RC2 before getting support. Once the final release is out it will be supported for years it is only the go live license that ends support as soon as the next version with a go live license is released.

To get all the new bits installed, including tooling updates for Visual Studio, head over to https://get.asp.net/. This is one of my favorite parts of the RC. The site will show you the appropriate links for install for the OS you are running on. Just make sure you hit the ASP.NET 5 RC install and not ASP.NET 4.6. The install link will kick you over to the install page of the docs site which provides step by step instructions in addition to the download link for the update.

After completing the install open global.json and update the sdk version to rc1-final.

Next is project.json the dependencies section as usual. In addition to the change from beta8 to rc1-final a few packages have changed names.

EntityFramework.SqlServer is not EntityFramework.MicrosoftSqlServer. Configuration and Logging moved from Mircosoft.Framework to Microsoft.Extensions.

Startup.cs had another set of changes this round. First up some namespace changes which are mostly the move from Microsoft.Framework to Microsoft.Extenstions.

In the Configure function I was able to enable browser link and it be useable and a slight change to the UseDatabaseErrorPage call.

Finally, a static void main was added for the entry point of the application. Pretty sure the app will still run without this change, but it is included when adding a new application with the updated templates.

Entity framework 7 only had a couple of breaking issue which seem to be the team finishing up some API tweaks. Here are the renames I hit this version.

Migration related renames
Old New
Index HasIndex
ForeignKey HasForeignKey
Annotation HasAnnotation

Something else I hit was an unexpected port when I ran the application. There is a new launchSettings.json file in the Project folder which is where things like port can be changed. It also has settings for IIS and IIS Express.

Finally make sure and check out the release page and the breaking changes page for this release.

Migration from ASP.NET 5 Beta 7 to Beta 8

ASP.NET 5 beta 8 was released on October 15th. Read the main announcement here and the entity framework 7 specific announcement here.

The tooling update can be found here. The relevant files are either DotNetVersionManager-x64.msi or DotNetVersionManager-x86.msi depending on what your system supports and WebToolsExtensionsVS14.msi.

The above gets everything needed for use inside Visual Studio for more details on other options check out Microsoft’s documentation for getting started with Windows, Mac or Linux.

After completing the upgrade open global.json and update the sdk version to beta 8.

Next up is project.json which has more changes than other migrations due to the move from hosting in Helios to Kestrel. First update beta7 to beta8 in the dependencies section.

Note that Microsoft.AspNet.Server.IIS and Microsoft.AspNet.Server.WebListener have been removed. Microsoft.AspNet.IISPlatformHandler and Microsoft.AspNet.Server.Kestrel have been added.

In the commands section the web command has been updated to use Kestrel.

As a result of the move to Kestrel both hosting.ini and wwwroot\bin\AspNetLoader.dll can be deleted. In wwwroot the web.config file changed to the following.

Startup.cs had a few changes. First in the constructor the application’s base path moved out of the constructor of ConfigurationBuilder to the SetBasePath function.

In ConfigureServices the setup for third-party authentication has been removed. For example the following has been removed.

Third party authentication options are now set in the Configure function. Here is an example with Facebook.

Also in the Configure function app.UseErrorPage is now app.UseDeveloperExceptionPage and app.UserErrorHandler is now app.UseExceptionHandler.

Add the platform handler to the request pipeline before app.UseStaticFiles.

In AccountController.GetCurrentUserAsync and ManageController.GetCurrentUserAsync Context is now HttpContext.

Next up are the changes related to entity framework 7. EF7 had a lot of API changes with this release. I am covering the ones related to the app I am working with and others can be found by looking at the commits related to this issue.

The designer.cs that goes with migrations drop the override of Id in favor of a migration attribute instead. The new attribute can be found in Microsoft.Data.Entity.Migrations.

Migration related renames
Old New
Key HasKey
Reference HasOne
InverseCollection WithMany
ConcurrencyToken IsConcurrencyToken
isNullable nullable

After all the above changes my project built, but would error because entity framework was trying to run migrations that had already been applied. After some digging I found that the table used to check if a migration has been applied or not had been renamed from MigrationHistory to EFMigrationsHistory. The following SQL will move the migrations that have been applied from the old table to the new one.

After fixing the migration issue the app ran with no problems. Make sure and check out the release page and the breaking changes page for this release.

Also note that the ASP.NET 5 project templates for Visual Studio have been open sourced and can be found here. The templates are a great resource which I used to work through a couple of issues when doing the migration to beta 8.

Add and Delete from an API

A few weeks ago I covered creating a basic API to retrieve contacts. In this post I am going to expand on that example by adding the ability to create and delete contacts. Before starting it would be a good idea to review my post on API basics as well as make sure you have a tool such as Postman to exercise your API.

First is the function for the creation of a new contact which will be an http post that accepts a contact, does some validation and inserts the contact to the database.

First thing to notice is the HttpPost attribute that says this function only handles HTTP posts. Next notice the FromBody attribute on the contact parameter of the function call. This tells ASP to bind the contact object to the data provided by the request body so that the function has a hydrated contact object to work with.

Both if statements are doing validation. The first is making sure that contact has a value. The second if is a bit of magic provided by ASP. ModelState contains information about the state of the model, a contact in this case, after it is bound to the values from the HTTP request. The contact model has data annotations which will cause ModelState.IsValid to return false if the model fails to validate against any of the data annotations. Both set of variations return a HttpBadRequest, but the ModelState version passes back the ModelState to the client since it contains details of all failed validation.

If all validation passed then the new contact is added to the controller’s dbContext and the dbContext saves changes inserts the new contact into the database.

Finally a route to the newly inserted contact is returned to the client. CreatedAtRoute takes a route name, route values and a value. In this case it is saying run the “GetById” route for the contacts controller with the ID of the new contact.

In order to get CreatedAtRoute to work the Get overload that takes an ID needed a name which is provided as part of the HttpGet attribute.

Now to add a contact with the API using Postman. First click Get which will drop down a list of HTTP verb to choose from. For adding a new contact we need to use Post.

postmanHttpVerb

After selecting post the body tab will be enabled. On the body tab select raw from the radio buttons. Next click the drop down that says text and select JSON (application/json) since the data for the contact will be sent to the API as JSON.

postmanBodyTypeFinally enter the appropriate JSON and click send. All that is required to create a new contact with my API is a name so the follow JSON is what I used to test.

At this point if all went well you will find John McTest in database. If all went well Postman will give the option to view the response which would include the Id which was set when dbContext.SaveChangesAsync was called.

The delete function is much simpler. It just needs the HttpDelete attribute and takes the ID of the contact to be deleted.

Using the dbContext the contact is retrieved for the ID passed in. If the contact is not found the function just returns since the contact has already been removed from the database. If the contact is found then the remove function of the dbContext is used to mark the contact for delete and then save changes of dbContext is used to send the delete command to the database.

To test with Postman select delete from the list of HTTP verbs, this is the same drop down that was used to select post above. Next enter the ID to be deleted in the URL box and click send. In the screenshot below the API will be told to delete the contact with the ID of 108.

postmanDelete

Check out the ASP.NET 5 docs for a great API example that uses Fiddler instead of Postman.

Aurelia with ASP.NET 5 and Web API

Update: A series of posts has been made covering this same topic with the RTM versions of both ASP.NET Core and Aurelia. The first post in the series can be found here.

Now that I have a web API for my contacts I wanted to go back and add a front end to view them. I decided this would also be a good time to try out one of the single-page application frameworks instead of using razor. The number of choices for a spa framework is almost over whelming. Angular, Ember, Meteor, etc. In the end I decided to try out Aurelia mostly based on the fact that Rob Eisenberg is behind it.

To get going I highly recommend going through Aurelia’s get started guide. In addition to being a great introduction to Aurelia I also had to pull at least one file out of the sample project to get up and running in my ASP.NET project.

A couple more resources I recommend reading before getting started are a couple of blog post by Scott Allen. The first covers getting jspm going in ASP.NET 5 and the second is a guide to get started with Aurelia in ASP.NET 5.

Now to get started. The first step is to install jspm which is yet another package manager. It can be installed using with the following npm command.

jspm utilizes GitHub in some cases to install packages so it is recommended that jspm be configured with a login or api token for GitHub to avoid any anonymous API request limits.

The remaining commands should be run from the project directory that contains the project.json file.

Next run jspm’s init command. This command will ask a series of questions. The default is fine for most of them. The exceptions being the server baseURL should be ./wwwroot and I chose to use Babel as my transpiler.

Now to install all the Aurelia bits that will be need to get an application up and hit a web API.

Next add an html file (any name is fine) to the wwwroot folder. This html file will be how the Aurelia application is accessed and the file does not have a lot in it. If you read either Aurelia’s getting started or Scott’s blog the following contents will look very similar.

When the above page loads Aurelia kicks in and looks for app.js and app.html. My app.js is based on the users.js from the getting started guide.

This class acts as the view model for my contact list. In the constructor function an http client is set up with a base url that matches the base url for the project’s web API which is http://localhost:14830/api/ in this case. The activate function is called by Aurelia and is where the contacts API is called using http.fetch. The import to fetch is the file I had to copy out of the Aurelia get started application into the wwwroot folder. You may also notice that the other imports are referencing specific folders with specific versions. This is not something that should be done for anything other than a short demo. I need to do some learning on gulp and what exactly Aurelia requires to get that fixed.

The following is the app.html.

The ${heading} is binding the value that will be displayed to the heading property defined in the app class. Next notice the repeat.for which will repeat the element it is defined on and its children foreach in the container to the right of the of statement. For example the above is going to print the name of each contact and all that contact’s email address contained in the contacts property of the app class. The resulting page is ugly, but the point is to prove Aurelia running and displaying the proper data.

At this point to remove some complexity I removed the authorize attribute off of the contacts controller and ran a test. As you may have guessed the test failed.

The failure was caused by the API returning a single object that then contain all the contacts instead of an array of contacts. The cause of this issue is the changes I made to work around serialization issue I was having with circular references  from my entity framework navigation properties.

The fix was to remove the following from the ConfigureServices function of the Startup class.

Then in all the contact related classes I added the JsonIgnore attribute to the property that pointed back to the contact model.

With those two changes everything started working. At this point I am not sure if that is the proper way to handle my issue or not. I have a feeling it will be something I will end up revisiting as I continue to learn more.

Migration from ASP.NET 5 Beta 6 to Beta 7

On September 2nd ASP.NET 5 beta 7 was released. As with beta 6 this release includes a tooling update for Visual Studio. Read the announcement here.

The tooling update can be found here. The relevant files are either DotNetVersionManager-x64.msi or DotNetVersionManager-x86.msi depending on what your system supports and WebToolsExtensionsVS14.msi.

After installing the tooling update change the sdk version in global.json to beta 7.

In the project.js file update beta6 to beta7 in the dependencies section.

In Startup.cs replace the Microsoft.Framework.Runtime namespace with Microsoft.Dnx.Runtime.

The remaining changes are related to entity framework 7. ApplyMigrations has been change to Migrate.

Any migration designer.cs files will need the following changes. The Microsoft.Data.Entity.Migrations.Infrastructure namespace is now Microsoft.Data.Entity.Infrastructure.

ContextType has changed to DbContext.

The ProductVersion property has been removed and BuildTargetModel is now protected.

The Microsoft.Data.Entity.Migrations.Builders namespace is now Microsoft.Data.Entity.Migrations.Operations.Builders.

Any classes that inherit from the Migration need the Up and Down functions changed to protected.

The AddCoumn of MigrationBuilder now needs a type specified and nullable has changed to isNullable.

The last change to MigrationBuilder that I ran into was with table.ForeginKey. referencedTable and referencedColumn changed to principleTable and principalColumns.

That was all the changes needed to get my test project updated. Here is the Github release page and breaking changes page for this release.

Migration of an existing project through the betas does work, but I recommend creating a new project every couple of betas. Things are changing in the project templates as well the core of ASP.NET 5. At the very least create a new project and look through the startup class and implement anything new that you find useful.  For example the debug logger is now included when creating a new project.

Basic Web API with ASP.NET 5

I am going to create basic web API access to the contacts data I have been using in previous posts. To start with I added an API folder to my project to hold my API controller. Next I added a contacts controller to the API folder by right clicking on the folder and selecting add new item.

AddNewItem

From the add new item under DNX selected Web API Controller Class, entered a name and clicked add.

AddNewItemDialog

From the resulting code I removed all the actions except for two get functions.

The above code contains a lot of new concepts I am going to break it down more.

The first thing to notice is the route attribute on the class declaration. The route attribute is how the routing engine determines where to send requests. Using [controller] tells the routing engine to use the class name minus the word controller. For example the above route handles api/contacts.

The constructor takes the DbContext needed to access contacts. Note that the context is being automatically injected via the constructor thanks to the fact that ASP.NET 5 now comes with dependency injection out of the box.

First get function returns all contacts and the second returns a specific contact based on the contact’s ID.

Note that the query contains three includes and each of the included classes contain a navigation property back to the main contact. For example here is the email address model.

All of the above compiles and seems to run fine, but will not provide a response. The navigation property for contact creates a circular reference that the response serializer throws an exception trying to serialize.

Thankfully the framework has a configuration option to work around this problem. In the ConfigureServices function of the Startup class add the following.

The above options marks the Contact property as a reference and does not try to circularly serialize it.

Now by running the project and going to http://localhost:port/api/contacts/1 in the browser I get all the contact data related to the contact with an ID of 1. I recommend using something like Postman to make the result more readable if you don’t have a front end to display the data.

Viewing SQL for Entity Framework 7 Queries

While writing this post on dealing with entity framework and collections I needed a way to see what SQL queries entity framework was sending to the database. At the time I used Express Profiler for the task.

expressProfiler

To get up and running with Express Profiler enter the server and authorization information and click the play button. Each event is logged in the grid. When an event is selected the actual query will show in the panel below the grid. The clear function is also very handy. Just hit it before triggering the entity framework query that you want to see the SQL for to minimize the number of event that have to be gone through.

I came across Express Profiler while watching Julie Lerman’s Looking Ahead to Entity Framework 7 Pluralsight course. This course is one of the ones provided free with a MSDN subscription so there is no reason not to check it. The course is a good introduction to Entity Framework 7. Keep in mind that the course is using beta 4 so things have changed some since it was released.

With the release of ASP.NET 5 Beta 6 a new debug logger was added to log to Visual Studio’s output window. This new logger seemed like it would be useful for logging entity framework queries.

In project.json add a dependency for Microsoft.Framework.Logging.Debug.

In the Configure function of the Startup class use the logger factory to add the new debug logger. This is done via the AddDebug extension method that comes when the new dependency was added above.

Run the application and the output window will contain the SQL that is sent to the database. The downside to this approach is that the log level of verbose outputs a lot of information making it harder to locate the SQL bits.

Migration from ASP.NET 5 Beta 5 to Beta 6

ASP.NET 5 Beta 6 was released on July 27th with the details from Microsoft in this blog post.  This release comes with a tooling update for Visual Studio 2015 and fewer breaking changes than beta 5.

Download and install the tooling update from here. Grab either DotNetVersionManager-x64.msi or DotNetVersionManager-x86.msi depending on what your system supports and WebToolsExtensionsVS14.msi. For WebToolsExtensionsVS14.msi there are language pack versions available for languages other than english.

With the tooling updates installed the following changes were made from Visual Studio. In global.json update the sdk version to beta 6.

For project.json in dependencies section update all the values from beta5 to beta6 except for  Microsoft.Framework.CodeGenerator.Mvc which stays at beta5.

In Startup.cs in the configure function in the is development section I was able to enable browser link and the UseErrorPage dropped the show all option.

The LogOff action of the AccountController changed to an async operation.

The rest of the changes I had to make are entity framework related. The call to apply migrations no longer requires the as relation call.

If you are trying to keep any existing migrations then changes will need to be made in them as well. There is a namespace change related to moving migrations out of the relational area.

The settings on auto incremented properties changed as well.

That is all there is to moving to beta 6 from beta 5. I am going to leave you with some reference links that may help if your project has issues with the move to beta 6.

Release page on Github with all the change in beta 6
Beta 6 Announcements Github page including breaking changes
ASP.NET 5 Roadmap