The source code for this post has been updated to VS 2017 and Angular 4 (master branch). There is also a VS2015 branch for Visual Studio 2015.

ASP.NET Core 1.0 and Angular 2 are probably the hottest new frameworks in terms of both of them are entirely re-written from scratch. We, as web developers are more than eager to test both of these two super promising frameworks and get ready to build cutting-edge applications. After writing the Building Single Page Applications using Web API and angularJS post which was fortunately widely liked by thousands of readers, I have started receiving comments in order to upgrade the same application we built on the previous post to ASP.NET Core 1.0, Angular 2 and of course Typescript. Though it would be nice to do it and have two different versions of the same application, I have finally decided to build an entirely different application cause it’s always nice to be creative and new stuff give you that opportunity. Once again, this post gonna be quite large so we will break it in to the following sections. You are strongly recommended to grab a cup of coffee before start reading the rest of this post:

Create and configure the application: Start with an empty ASP.NET Core application and configure it step by step for using ASP.NET MVC 6. We will also install all the server and client packages we ‘ll need to build the SPA (project.json, package.json (NPM), gulpfile.js (Gulp), bower.json (Bower)).

Entity Framework Core: Configure EF Core Code First migrations and write a database initializer. We will also create the back-end infrastructure Entities, Reposistories and set the Dependency Injection as well.

What are we going to build

We will create a Single Page Application to display a gallery’s photos. The landing (default) view will present some information about the app such as the technologies used for building the application.
When user clicks the Photos tab the corresponding component is being rendered, displaying some photos to the user. Pagination is also supported.
The Albums tab displays using pagination features the albums existing in the gallery. In order to view this component the user needs to be Authorized. This means that the user will be automatically redirected to the Login component if he hasn’t logged in yet.
An authenticated user can click and display a specific albums’s photos where he can also remove any of them. Before removing a photo a confirmation popup message appears. More over, a notification service display success or error messages.Sign in and Registration components are pretty much self-explanatory. Validation messages will inform the user for required fields.
All views should be rendered smoothly in all types of screens (desktops, tablets, mobiles..) giving the sense of a responsive application.

What are we going to use

The essence of post is the technologies, frameworks and tools we are going to use to build the PhotoGallery Single Page Application. It’s gonna be a pure modern web application built with the latest patterns and tools exist at the time this post is being written. Let’s view all of them in detail.

Entity Framework Core: The latest version of the Entity Framework Object Relational Mapper.

Angular 2: The famous AngularJS re-written and re-designed from scratch. Angular 2 is a development platform for building mobile and desktop applications

TypeScript: A typed super-set of JavaScript that compiles to plain JavaScript. One of the best ways to write JavaScript applications.

NPM: A Package Manager responsible to automate the installation and tracking of external packages.

Bower: A Package Manager for the Web and as it’s official website says, optimized for the front-end.

Gulp: A task runner that uses Node.js and works in a Streamline way.

This post assumes that you have at least a basic understanding of the last four pre-mentioned languages & tools (TypeScript, NPM, Bower and Gulp) but in case you don’t, that’s OK, this post will get you ready right away.

Prerequisites

In order to build modern and cross-platform Web Applications using the pre-mentioned tools, you need to prepare your development environment first. Let’s view them one by one.

Integrated development environment (IDE): In this post we ‘ll use Visual Studio 2015 which you can download from here but you can also use Visual Studio Code which you can download from here. The latter is one way option for MAC and Linux users. At the end, the project should be able to run outside Visual Studio as well. In case you chose to install Visual Studio 2015, just make sure to specify that you want to include the Microsoft Web Developer Tools.

ASP.NET Core 1.0. That’s the super promising, open-source and cross-platform Microsoft’s framework. Depending on which platform you want to start coding ASP.NET Core 1.0 applications, you need to follow the respective steps described here. Make sure to follow the exact instructions cause otherwise you may face unexpected errors. In my case I installed ASP.NET Core on a Windows 10 PRO computer. Started with the Visual Studio official MSI Installer…
And the NuGet Manager extension for Visual Studio..
If Microsoft releases a new version, I will always try to update the source-code.

NPM. We need to install NPM which is the Node.js Package Manager. Though Visual Studio 2015 has build in support for installing NPM or Bower packages, there are many times that it fails and then you need to run manually the command from a console. Installing node.js from here will also install NPM as well. Check it by typing the following command in a console.

npm -v

Bower, Gulp, TypeScript, Typescript Definition Manager. Visual Studio can also run Gulp tasks right from its IDE but we supposed to make this app cross-platform available so make sure you install globally all the following by typing the commands on the console:

npm install -g bower

npm install -g gulp

npm install -g typescript

npm install -g tsd

npm install -g typings

Create and configure the application

It is time to create the PhotoGallery Single Page Application which is going to be an ASP.NET MVC 6 application. In this section will create the solution and configure the ASP.NET Core 1.0 application to make use of the ASP.NET MVC 6 services. More over we will setup all the client tools (NPM/Bower packages, Gulp and Typescript) so we can start coding in both server and client side accordingly. In Visual Studio 2015 create an ASP.NET Core Web Application by selecting the Empty template.
Here is the default structure of an empty ASP.NET Core web application.
Feel free to remove the Project_Readme.html file. The project.json is a very important file where we declare what packages we want our application to use and what are the frameworks our application will target.
Alter the project.json file as follow and click save.

By the time you save the file, Visual Studio will try to restore all the packages.
If you were outside Visual Studio you would have to run the following command:

dotnet restore

..where dotnet comes from the .NET Core CLI which replaces the old DNX tooling. This means no more DNX, dnu or dnvm commands, only dotnet. Find more about their differences here. Let’s explain a little what we did in the project.json. First we declared some variables such as the webroot which we ‘ll read its value from the gulpfile.js later when we ‘ll declare some tasks. The userSecretsId is required in order to run Entity Framework Code First migrations related commands (acts as a unique ID for the application). Then we declared the dependencies or the packages if you prefer that our application needs. The first two of them are for hosting the app with or without IIS. The .Mvc related packages are required to add and use MVC services to the services container or in other words.. to use MVC 6 in our application. Then we declared the Entity Framework related packages in order to use EF 7 for data accessing. The Extensions packages will help us to easily access some .json files from the code. As you may have noticed we will make use of the Automapper package as well to map EF entities to the relative ViewModel objects. Last but not least is the Microsoft.AspNetCore.Authentication.Cookies which will ‘ll use in order to set Cookie based authentication. If i was to start my application outside IIS or Visual Studio, all I have to do is run the following command in the terminal.

dotnet run

Mind that you need to navigate to the root of your application folder (where the package.json exists) before running this command. We ‘ll use the EF command to run Entity Framework migration commands later on.
Let’s continue. Right click your application (not the solution) and add a new item of type NPM Configuration File. Leave its default name package.json. From now and on when I say application root i mean the src/PhotoGallery folder which is the actual root of the PhotoGallery application. Change the contents of the package.json as follow.

By the time you save the file, Visual Studio will try to restore the NPM packakges into a node_modules folder. Unfortunately for some reason, it may fail to restore all packages.
All you have to do, is open the terminal, navigate at the application’s root folder and run the following command.

npm install

As soon as all packages have been restored, Visual Studio will also detect it and stop complaining (it may crash during package restoring but that’s OK..). As far as what packages we declared, it’s pretty obvious. We needed the required packages for Angular 2, some Gulp plugins to write our tasks and a few other ones such as fancybox or jQuery. Let’s configure the libraries we want to download via Bower. Right click the project and add a new item of type Bower Configuration File. Leave the default name bower.json. You will notice that under the bower.json file a .bowerrc file exists. Change it as follow in order to set the default folder when downloading packages via bower.

Now you can understand why it’s crucial to have those tools globally installed on our computer. Let’s finish this section by writing the gulp tasks. Right click your project and add a new item of type Gulp Configuration File. Leave its default name gulpfile.js and change its contents as follow.

I know that it may seems large and difficult to understand but believe me it’s not. Before explaining the tasks we wrote I will show you the result of those tasks in solution level. This will make it easier to understand what those tasks are trying to accomplish.
Pay attention at the wwwroot/lib folder. This folder is where the client-side dependency packages will end. The lib/css will hold files such as bootstrap.css, font-awsome.css and so on.. Similarly, the lib/js will hold all the JavaScript files we need to write Amgular 2 applications using TypeScript. You may wonder where exactly are we going to write the actual angular SPA? The spa will exist under the wwwroot/app folder with all the custom Typescript files. A specific task named compile-typescript will compile those files into pure JavaScript and place them in to the wwwroot/lib/spa. Let’s view the Gulp tasks:

setup-vendors: Place all required external JavaScript, CSS, images and font files into the corresponding folder under lib.

compile-typescript: Compiles all Typescript files under wwwroot/app folder and place the resulted ones into the respective folder under wwwroot/lib/spa/

watch.ts: A listener to watch for Typescript file changes. If a change happens the run the compile-typescript task. This task will help you a lot during development.

clean-lib: Deletes all the files under wwwroot/lib folder.

build-spa: Runs the setup-vendors and compile-typescript tasks.

It wasn’t that bad right? Now take a notice at the following line inside the gulpfile.js.

var tsProject = ts.createProject('./wwwroot/tsconfig.json');

In order to compile Typescript you need some Typescript specific compiler options. This is what the tsconfig.json file is for. Right click the wwwroot folder and create a new item of type Typescript JSON Configuration file. Leave the default name tsconfig.json and paste the following contents.

This configuration file not only will be used for compilation options but it will also be used from Visual Studio for intellisense related Typescript issues. Build the application and open the Task-runner window. Run the build-spa or the setup-vendors task. I know there are no Typescript files to compile but you can see the automatically created folders under wwwroot/lib with the files we defined. In case you have any troubles running the task, you can open a terminal and run the task as follow:

gulp setup-vendors

Entity Framework Core

The final goal of this section is to configure the services that our application will use, inside the Startup.cs file. At this point if you run the PhotoGallery application you will get a Hello World! message coming from the following code in the Startup class.

The schema we want to create is very simple. A Photo entity belongs to a single Album and an Album may have multiple Photo entities. A User may have multiple roles through many UserRole entities.
Let’s create the DbContext class that will allow us to access entities from the database. Create a folder named Infrastructure under the root of the application and add the following PhotoGalleryContext class.

You should be able to resolve all the required namespaces because we have already installed the required packages. We ‘ll proceed with the data repositories and a membership service as well. Add a folder named Repositories with a subfolder named Abstract under Infrastructure. Add the following to files/classes.

Notice that I have added some operations with includeProperties parameters. I did this cause Entity Framework Core doesn’t support lazy loading by default and I’ m not even sure if it will in the future. With that kind of operations you can load any navigation properties you wish. For example if you want to load all the photos in an album you can write something like this.

There are so many ways to implement data repositories that I won’t even discuss. We have seen much better and scalable implementations many times on this blog but that’s more than enough for this application. Let’s create now the two services required for membership purposes. Add a folder named Services under Infrastructure and create a subfolder named Abstact with the following interfaces.

Data repositories will automatically be injected into MembershipService instances. This will be configured in the Startup services later on. And of course we need the MembershipContext which holds the IPrincipal information for the current user. Add the class inside a new folder named Core under Infrastructure.

One last thing remained to do before configuring the services is to create a Database Initializer class to run the first time you run the application. The initializer will store some photos, create an admin role and a default user (username: chsakell, password: photogallery). Of course when we finish the app you can register your own users as well. Add the DbInitializer under the Infrastructure folder.

The photos will be initialized from a folder wwwroot/images where I have already stored some images. This means that you need to add an images folder under wwwroot and add some images. You can find the images I placed here. I recommend you to copy-paste at least the thumbnail-default.png and the aspnet5-agnular2-03.png images cause the are used directly from the app.
Now let’s switch and change the Startup class as follow:

Lots of stuff here so let’s explain from the top to bottom. The constructor simply sets the base path for discover files for file-based providers. Then sets an appsettings.json file to this configuration which means that we can read this file through a instance of IConfigurationRoot. The question is what do we want the appsettings.json for? Well.. we want it to store the connection string over there (Say good riddance to Web.config..). Add an appsettings.jsonJSON file under the root of PhotoGallery application and paste the following code.

Alter the connection string to reflect your database environment. Moving on, the ConfigureServices function adds the services we want to the container. Firstly, we add Entity Framework services by configuring the connection string for the PhotoGalleryContextDbContext. Notice how we read the appsettings.json file to capture the connection string value. Then we registered all the data repositories and services we created before to be available through dependency injection. That’s a new feature in ASP.NET 5 and it’s highly welcomed. We added Authentication and Authorization services as well by registering a new Policy. The Policy is a new authorization feature in ASP.NET Core 1.0 where you can declare requirements that must be met for authorizing a request. In our case we created a new policy named AdminOnly by declaring that this policy requires that the user making the request must be assigned to role Admin. If you think about it this is quite convenient. Before ASP.NET Core 1.0, if you wanted to authorized certain roles you would have to write something like this.

Now you can create a Policy where you can declare that if one of those roles are assigned then the request is marked as authorized. Last but not least, we added the MVC services to the container. The Configure method is much simpler, we declared that we can serve static files, we added Cookie based authentication to the pipeline and of course we defined a default MVC route. At the end, we called the database initializer we wrote to bootstrap some data when the application fires for the first time. I have left an AutoMapperConfiguration.Configure() call commented out but we ‘ll un-commented it when the time comes. At this point we can run some Entity Framework commands and initialize the database. In order to enable migrations open a terminal at the root of the application where the project.json leaves and run the command:

dotnet ef migrations add initial

This command will enable migrations and create the first one as well.
In case you run the command through VS package manager console, make sure to navigate to src/PhotoGallery path first by typing cd path_to_src_PhotoGallery.
In order to update and sync the database with the model run the following command:

dotnet ef database update

Single Page Application

This section is where all the fun happen, where ASP.NET MVC 6, Angular 2 and Typescript will fit together. Since this is an MVC 6 application it makes sense to start with HomeController MVC controller class, so go ahead and add it under a Controllers folder at the root of PhotoGallery.

We have to manually create the Index.cshtml view but first let’s create a common layout page. Add a Views folder at the root and add a new item of type MVC View Start Page in it. Leave the default name _ViewStart.cshtml.

@{
Layout = "_Layout";
}

Add a folder named Shared inside the Views folder and create a new item of type MVC View Layout Page named _Layout.cshtml. This is an important item in our application cause this page can act as the entry point for multiple SPAs in our application, in case we decided to scale it.

If you take a look at this page you will notice that this page contains everything that an Angular 2 application needs to get bootstrapped. No top-bar or side-bar components exist here but only Angular 2 related stuff. More over there are some custom sections that an MVC View can use to inject any custom required scripts or stylesheets. One more thing to notice is the src references that starts with ~/lib which actually point to wwwroot/lib.
At this point create the systemjs configuration which will instruct systemjs how to load any module our application needs. Create the required SystemJS configuration in an systemjs.config.js file at application’s root:

Apparently there is going to be an Angular 2 component with a selector of photogallery-app bootstrapped from a file named app.js. This file will be the compiled JavaScript of a Typescript file named app.ts. I have also included a custom css file named site.css which you can find here. Place this file in a new folder named css under wwwroot. You may expect me now to show you the app.ts code but believe it’s better to leave it last. The reason is that it requires files (or components if you prefer) that we haven’t coded yet. Instead we ‘ll view all the components one by one explaining its usage in our spa. First of all I want to show you the final result or the architecture of PhotoGallery spa in the Angular 2 level. This will make easier for you to understand the purpose of each component.
The design is quite simple. The components folder hosts angular 2 components with a specific functionality and html template as well. Notice that the .html templates have an arrow which is new feature in Visual Studio. It means that this .html file has a related Typescript file with the same name under it. When we want to render the Home view, then the home.html template will be rendered and the code behind file the template will be a Home Angular 2 component. I have placed all components related to membership under an account folder. The core folder contains reusable components and classes to be shared across the spa. Let’s start with the simplest one the domain classes. Add a folder named app under wwwroot and a sub-folder named core. Then create the domain folder under core. Add a new Typescript file name photo.ts to represent photo items.

Since this is the first Typescript file we added in our spa, you can test the Gulp task compile-typescript and ensure that everything works fine with Typescript compilation.
You could run the task from command line as well.

gulp compile-typescript

This photo Typescript class will be used to map photo items come from the server and more particularly, ViewModel photo items. For each Typescript domain class there will be a corresponding ViewModel class on the server-side. Create a folder named ViewModels under the root of PhotoGallery application and add the first ViewModel PhotoViewModel.

The next thing we are going implement are some services using the @Injectable() attribute. (I’m gonna call them services during the post but there are actually injectable modules..) We ‘ll start with a service for making Http requests to the server, named dataService. Add a folder named services under app/core and create the following Typescript file.

We imported the required modules from ‘@angular/http’ and ‘@angular/core’ and we decorated our DataService class with the @Injectable attribute. With that we will be able to inject instances of DataService in the constructor of our components in the same way we injected here http. This is how Angular 2 works, we import whichever module we want to use. I have written here some get and CRUD operations but you can add any others if you wish. Let’s implement a membershipService which allow us to sign in and log off from our application. Add the membership.service.ts file in the services folder as well.

Quite interesting service right? Notice how we imported our custom domain classes and the DataService as well. We also marked this service with the @Injectable() attribute as well. This service is going to be injected in to the Login and Register components later on. The login and register operations of the service, simply sets the api URI and makes a POST request to the server. We also created two functions to check if the user is authenticated and if so get user’s properties. We will see them in action later. There are two more services to implement but since we finished the membershipService why don’t we implement the corresponding server-side controller? Add the following AccountController Web API Controller class inside the Controllers folder.

Here we can see the magic of Dependency Injection in ASP.NET Core 1.0. Required repositories and services are automatically injected into the constructor. The Login, Logout and Register actions are self-explanatory. Let’s finish with the Angular services by adding the following two helpers into the app/core/services folder.

This is a very interesting service as well and I created it for a reason. I wanted to support notifications in our SPA so that user receives success or error notifications. The thing is that I couldn’t find any external library available to use it with Typescript so I thought.. why not use a JavaScript one? After all, Typescript or not at the end only JavaScript survives. I ended up with the alertify.js which we have already included in our app using bower. I studied a little the library and I figured out that there is an alertify object that has all the required notification functionality. And this is what we did in our Angular service. We made the trick to store this variable as any so that we can call its methods without any intellisense errors.

private _notifier: any = alertify;

On the other hand the alertify variable is unknown to the NotificationService class and we get an intellisense error. More over if you try to compile the Typescript using the compile-typescript task you will also get a relative error Cannot find name ‘alertify’.
The question is.. can we live with that? YES we can.. but we have to make sure that we will allow Typescript to be compiled and emit outputs despite the type checking errors occurred. How did we achieve it? We have already declared it in the tsconfig.json file as follow:

This means that if the external JavaScript library contains a variable or function you want to use it in your TypeScript class, you declare it outside the class. It’s very important to declare it outside the class, otherwise the local variable will override the one defined in the external library. The following code would crash.

Angular 2 Components

The next thing we are going to implement are the basic Components of our application. Each component encapsulates a specific logic and is responsible to render the appropriate template as well. Let’s number them along with their specifications (click them to view the template they render).

AppComponent: The SPA’s root component. It acts as the root container component

HomeComponent: The default component rendering when the application starts.

PhotosComponent: The component responsible to display PhotoGallery photos. It supports pagination and is available to unauthenticated users.

AlbumsComponent: The component responsible to display PhotoGallery albums. It requires authorization and supports pagination as well.

This is by far the simplest Angular component you will ever seen. We used the @Component annotation and we declared that when this component is active, a template named home.html existing inside app/components will be rendered. Add the home.html template underapp/components. This is simple html with no Angular related code and that’s why I won’t paste it here. You can copy-paste its code though from here. The next component will spice things up. It’s the PhotosComponent, the one responsible to display all photos existing in PhotoGallery app with pagination support as well. It will be the first time that we ‘ll use the dataService injectable to make some HTTP GET requests to the server. Add the photos.component.ts file under app/components folder.

The getPhotos() function invokes the DataService.get method which returns an Objervable<any>. Then we used the .subscribe function which registers handlers for handling emitted values, error and completions from that observable and executes the observable’s subscriber function. We used it to bound the result come from the server to the Array of photos items to be displayed. We also set some properties such as this._page or this._pageCount which are being used for pagination purposes. At the moment you cannot find those properties cause they are inherited from the Paginated class. I have created this re-usable class in order to be used from all components need to support pagination. It doesn’t matter if the component needs to iterate photos, albums or tomatos.. this re-usable component holds the core functionality to support pagination for any type of items. Add the paginated.ts Typescript file inside a new folder named common under app/core.

The properties of t this class are used to render a paginated list (we ‘ll view it soon in action). When the user click a number or an first/previous/next/last arrow, the component that inherits this class, the only thing needs to do is to set the current page and make the request. All the other stuff happens automatically. Let’s view the app/components/photos.component.html template now.

The [routerLink] will create a link to the Home component. We used the new angular directive to iterate an array of photo items.

*ngFor="let image of _photos"

The footer element is the one that will render the paginated list depending on the total items fetched from the server and the paginated properties being set. Those properties are going to be set from the server using a new class named PaginatedSet.
Let’s switch and prepare the server-side infrastructure for this component. Add the following class inside the Infrastructure/Core folder.

The Get action returns a PaginatedSet containing the PhotoViewModel items to be displayed and the required paginated information to create a client paginated list. The thing is that we haven’t set any Automapper configuration yet and if you recall, I have told you to keep an Automapper related line in the Startup class commented out until the time comes. Well.. why don’t we configure it right now? Add a new folder named Mappings under Infrastructure and create the following class.

The code creates mappings for both Photo to PhotoViewModel and Album to AblumViewModel objects. For the former we only add an images prefix for the photo URI so that can be mapped to wwwroot/images folder and for the latter we set the TotalPhotos property as well. In the same folder add the AutoMapperConfiguration class as follow.

Now you can safely uncomment the following line from the Configure(IApplicationBuilder app) function in the Startup class.

AutoMapperConfiguration.Configure();

The albums angular component is almost identical to the photos one with one exception. It uses a routing related directive [routerLink] in order to redirect to the albumphotos component when user clicks on a specific album. Thus before showing the code I believe it is necessary to introduce you to the routing configuration our SPA will follow. Let’s discuss the architecture shown in the following schema.
As of Angular 2 RC.5 and later we are recommended to create three files to bootstrap an angular app. An app.module.ts to declare our app’s module, an app.component.ts to act as the root container-shell and a main.ts to bootstrap the main module. We can add routing configuration inside our module and since we can define as many modules as we wish, each module may have its own routing configuration. In our case, we ‘ll define the basic routes in app.module.ts and all routes related to membership in an account.module.ts. We will define the basic routs inside a routes.ts file under the app folder.

We set nothing here, we have only defined an object with an array of Routes. The Routes variable reflects exactly the previous picture. Pay attention the way we ‘ll pass an id paramater when we navigate to view a specific album’s photos. At this point we haven’t coded that component yet but that’s OK, we ‘ll do it a little bit later. Let’s continue from where we have stopped, the Albums component. Add the albums.component.ts Typescript file under app/components.

I have intentionally made the DataService.get() method to return an Observable<Response> rather than the JSON serialized result because I know that my API call my return an unauthorized code. Hence, if an error occurred and the status is 401 we navigate to the login template else we proceed to serialize the result. It’s up to you what you prefer, I just wanted to show you some options that you have. Let’s view the related template albums.component.html. Add it under the same folder app/components.

The highlighted lines shows you the way you can check programmatically if the current request is authorized to access a specific part of code. We used an instance of Microsoft.AspNet.Authorization.IAuthorizationService to check if the ClaimsPrincipal user fullfiles the requirements of the AdminOnly policy. If not we return a new object of type StatusCodeResult with a 401 status and a message. You can add that class inside the Infrastructure/Core folder.

OK, we prevented access to the api/albums/get API but was this the right way to do it? Of course not because the way we implemented it we do allow the request to dispatch in our controller’s action and later on we forbid the action. What we would like to have though is a cleaner way to prevent unauthorized access before requests reach the action and of course without the use of the Microsoft.AspNet.Authorization.IAuthorizationService. All you have to do, is decorate the action you want to prevent access to with the [Authorize(Policy = “AdminOnly”)] attribute. Do if for both the actions in the AlbumsController. You can now safely remove the code that programmatically checks if the user fullfiles the AdminOnly policy.

We will procceed with the AlbumPhotosComponent angular component which is responsible to display a respective album’s photos using pagination. We will see two new features on this component: The first one is the ActivatedRoute which will allow us to extract the :id parameter from the route api/albums/:id/photos. The second one is a confirmation message which will ask the user to confirm photo removal. Add the albums-photos.component.ts file inside the app/components folder.

When user clicks to delete a photo, a confirmation dialog pops up. This comes from the notificationService.printConfirmationDialog method, that accepts a callback function to be called in case user clicks OK.

If removal succeeded we display a success message and refresh the album photos. It’s time to implement the membership’s related components. As we have allready mentioned, there is a nested routing configuration for those components so let’s start by creating this first. Add a new folder named account under app/components and create the following routes.ts file.

This file is almost identical with the one we created under app with the difference that difines different routes. Those routes will be added in the account.module.ts file. Add the LoginComponent component in a login.component.ts Typescript file under app/components/account.

We inject the MemberhipService in the constructor and when the user clicks to sign in we call the membershipService.login method passing as a parameter user’s username and password. We subscribe the result of the login operation in a OperationResult object and if the authentication succeeded we store user’s credentials in a ‘user’ key using the localStorage.setItem function. Add the related login template in a login.component.html file under app/account/components.

Here is where all account related components are bound together. In an NgModule we declare any component we are going to use, directive, pipe or custom services. We also declare the routing configuration we want to use. Now its time for the application's root module where we also are going to define the AccountModule as well. Let's create first the app.module.ts file under the app folder.

We imported all modules that our app needs in order to function properly. Notice the AccountModule import which internally defines its own routing system as we saw previously. We also declare the components and services to be used by our app. Here is the app.component.ts definition.

The component exposes some membership related functions (login, logout, getUsername) which will allow us to display the user's name and a logout button if authenticated and a login button if not. As of Angular 2 RC.5 we need to define an NgModule. Add the following app.module.ts under wwwroot/app.

We created a BaseRequestOption class in order to override the default options used by Http to create and send Requests. We declared that we want the Content-Type header to be equal to application/json when making http requests to our Web API back-end infrastructure. We have also made our custom services available through our application. Add the following main.ts file under wwwroot/app as well.

This file is responsible to bootstrap the SPA. The app.component.html template the will host two important features. The first one is the navigation top-bar and of course the main router-outlet. Add it under wwwroot/app folder.

Since the top-bar is html elements of the base host component, it will be always displayed whichever component and route is active. Believe it or not, we have finished building the PhotoGallery cross-platform ASP.NET Core 1.0 Single Page Application. At this point you can run the build-spa Gulp task, build and run the application. Let's view the final result with a .gif:.

Discussion

Single Page Application Scalability

One thing you may wonder at the moment is.. I cannot remember referensing all those components we have coded (e.g. Home, Login, Albums..) in any page, so how is this even working? The answer to this question will show us the way to scale this app in case we wanted to provide multiple views. Let me remind you first that when the compile-typescript task runs all the transpiled files end in the wwwroot/lib/spa folder. Hense, we should wait to find the transpiled result of our root component AppRoot in a wwwroot/lib/spa/app.js file. This is the only file you need to reference in your page that will eventually host this single page application. And which is that page? The Index.cshtml of course..

All the required components and their javascript-transpiled files will be automatically loaded as required using the universal dynamic module loader SystemJS. Let's assume now that we need to scale this app and create a new MVC View named Test.cshtml and of course we want to bootstrap a hall new different Single Page Application. This Test.cshtml could use the default _Layout.cshtml page which is a bootstrap template that references only the basic libraries to start coding Angular 2 applications. All you have to do now is create a new root component, for example AppRootTest in a typescript file named apptest.ts under wwwroot/app. This component will probably has its own routes, so you could create them as well. If you see that your application gets too large and you code too many root components, you can place all of them under a new folder named wwwroot/app/bootstrappers. Then part of the Test.cshtml page could look like this.

As you can see this page will only load the root component AppTest and its related files as well.

ASP.NET Core 1.0 architecture

In case this isn't your first time you visit my blog, you will know that I always try to keep things clean as far as instrastrure concerns. Yet, on this application I kept all data repositories and services inside the web app. I did it for a reason. First of all I excluded the classic c# class libraries. ASP.NET Core 1.0 is a cross-platform framework, it isn't supposed to work directly with those libraries. MAC and linux users have probably no clue what a c# class library is. So an alternative option may would be to use ASP.NET Core 1.0 class libraries (packages). Those types of projects are cross-platform compiled and can target multiple frameworks. At the time though this post was written, I found that they weren't that much stable to use them in this app so I decided to focus on the Web only. I am very sure that time will show us the best way to architect the different components in a ASP.NET Core 1.0 application. When this time comes, I will certainly post about it.

Conlusion

Building the PhotoGallery application was a great experience for me and I hope so for you as well. I believe that ASP.NET Core 1.0 will help us build more robust, scalable and feature-focused applications. The option where we can only install what we only want to use is simply great. The idea that you have no unnecessary packages installed or unnecessary code running behind the scenes makes you think that you build super lightweighted and fast applications. Same applies for Angular 2 for which I found that coding with it had a lot of fun. Import only what you actually want to use, inject only what actually need to inject, nothing more. Let's recap at this point the best features we saw on this post.

Create and configure an ASP.NET Core 1.0 application to use MVC 6 services.

View in action several Angular 2 features such as Routing, nested routing, Components, HTTP requests.

CRUD operations using Angular 2 and Typescript

Form validation with Angular 2

The source code of the PhotoGallery app is available on GitHub and in case you haven't followed coding with me, you will also find detailed instructions to run it over there. You can submit your comments for this post on the comments area.

In case you find my blog’s content interesting, register your email to receive notifications of new posts and follow chsakell’s Blog on its Facebook or Twitter accounts.

Im trying to run the app on Ubuntu 16.04. There is a possible problem with the sql server. The app compiled without any errors. But further, many SQL related exceptions have been thrown. Can u help me set up the server on Ubuntu?

Christos, To enable EF Migrations, this doesn’t work with the latests prerequisites:
dotnetcore migrations add initial
Could it be that dotnetcore is from the older DNX versions? In the past, I’ve been using NuGet Console to Add-Migration and Update-Database.

Thanks! I had an old ASP.NET 5 RC2 version of dotnet that refused to uninstall. Eventually got rid of it and re-installed pre-requsites and finally got the latest dotnet cli working. One note, I needed to modify the DB connection string in appsettings.json to: Server=(localdb)\\mssqllocaldb; and was able to get the dotnet ef dateabase update to run, and the initial vaues. Works like a charm now, thanks again.

Hello. Thank you for great article, but I bit confused about using SqlServer, it will definitely work on Windows machine, but how we could launch this project on Linux or Mac without installed SqlServer? Sorry if this question stupid, maybe I missed something.

Hi Den, good question. Indeed you need an instance of SqlServer to launch the project. From now on I will try to use the InMemory provider in order to launch projects easier in all platforms. Here is a pull request a fellow sent for those who want to change to InMemoryDb provider.

Hi, this is an excellent tutorial and I followed it to the letter yet could not get it to work properly. I then decided to cheat and downloaded the complete source and compiled it, which works great but I am getting script dependency errors in my browser as follows;

Can you tell me what would be an efficient way to implement the ability to edit account information? So let’s say someone created an account but wants to edit their e-mailadress. Is there a easy way to get around this with using chunks of code already in the registration components? I guess it would be possible to show the same dialog as registering has filled with known user information that can be edited and sent to the database.

Wonderful tutorial which really helped me a lot. Is there an easy way to retrieve specific userdata from the database? I’m able to retrieve data stored in localStorage which holds the username, password and remember me flag but I would like to know how to retrieve a user’s emailaddress from the database and display it somewhere.

Thank you for this tutorial. I found that VS 2015 fails to restore all the NPM packages into node_modules folder and the npm folder is with not installed error. Please could I know where should I run the command “npm install” which you have suggested.

Sometimes VS complains that there is an error while trying to install NPM packages but it actually has installed them. Any way, just to make sure you have downloaded the NPM packages, open a terminal, navigate to src/PhotoGallery where the package.json file exists and run the following command:

After following instructions from top to bottom, and after fighting through some odds and ends, I am finally up and running as well! This is one of the more excellent posts I have encountered in a long time. Thank you, sir!

Hi, I have a question. What if client was completely separated from the server (client is on one machine and server on another), how to retrieve photos in that scenario? I am guessing one would have to retrieve actual photo somehow from the server, because Uri is not enough? Thank you in advance.

The purpose of this blog is to broaden my education, promote experimentation and enhance my professional development. Albert Einstein once said that “If you can’t explain it simply, you don’t understand it well enough” and I strongly believe him!