Nov
8
Written by:
Michael Washington
11/8/2016 12:21 PM
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_8.png)
Note: This tutorial is part of a series of articles that create a complete Angular 2 application using OData 4 and ASP.NET 4:
- Hello World! in Angular 2 using Visual Studio 2015 and ASP.NET 4
- Implement ASP.NET 4 MVC Application Security in Angular 2 Using OData 4 (this article)
- Tutorial: Creating An Angular 2 CRUD Application Using MVC 5 and OData 4
- Tutorial: An End-To-End Angular 2 Application Using MVC 5 and OData 4
You can implement ASP.NET 4 MVC Application security in your Angular 2 applications.
This is important because ultimately your data must be secured on the server side. The Angular 2 application is only provided data that the server side methods expose to it.
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_c6d570b3-fe6a-4415-8fd4-c07190d6d618.png)
The server side methods make these decisions based on the security established when the user logs into the ASP.NET 4 MVC website.
Note: to log a user in directly through the Angular application, see: Angular 2+ Logging Into An ASP.NET 4.5 Application.
Creating The Application
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_7.png)
For this demonstration, we start with the application created in Hello World! in Angular 2 using Visual Studio 2015 and ASP.NET 4.
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_d27a9f6e-a8d1-40cc-8ca5-90685ca655e9.png)
First, go to Tools, NuGet Package Manager / Manage NuGet Packages for Solution…
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_60d2f441-ceb2-451c-80c7-fe8848b7e58d.png)
Select Updates, Select all packages, then click Update.
Answer yes to any screens that appear.
A restart may be required.
We now need to install OData 4.
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_82cc0147-b09d-42f6-accf-236252bf8e18.png)
We go to the NuGet package Manager Console …
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_cc917fb1-004a-4636-91ff-6f0de822fba2.png)
… click to the right of the PM> symbol and paste the entire list:
Install-Package Microsoft.AspNet.WebApi.WebHost
Install-Package Microsoft.AspNet.OData
It will take some time, but it will install all the packages.
(note: You will usually have to press return when it gets to the last package to install it).
(note: If the OData Client does not install (it throws an error), it is not an issue).
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_1526b19a-cad9-4d7f-99b2-947360595c8f.png)
Add a file to the App_Start folder called WebApiConfig.cs using the following code:
using Angular2QuickStart.Models;
using Microsoft.OData.Edm;
using System.Web.Http;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
namespace Angular2QuickStart
{
class WebApiConfig
{
#region Register
public static void Register(HttpConfiguration config)
{
// OData routes
// These must be configured before the WebAPI routes
config.MapHttpAttributeRoutes();
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: GenerateEntityDataModel());
// Web API routes
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
#endregion
#region GenerateEntityDataModel
private static IEdmModel GenerateEntityDataModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
// CurrentUser function
var CurrentUserFunction = builder.Function("CurrentUser");
CurrentUserFunction.Returns<User>();
return builder.GetEdmModel();
}
#endregion
}
}
This creates the routes needed to enable OData.
Note, all the code has not been added yet, so the code will not compile at this point.
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_2fa910a4-82de-48ae-a9ea-4aee64497f19.png)
Open the Global.asax.cs file and add the following using statement:
using System.Web.Http;
In that file, replace the Application_Start() method with the following code:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
This configures the application to call the WebApiConfig class that was just added.
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_03a218b2-c2ec-4f9b-b38e-02a877393b91.png)
Add a User.cs file in the Models folder using the following code:
using System.ComponentModel.DataAnnotations;
namespace Angular2QuickStart.Models
{
public class User
{
[Key]
public string UserName { get; set; }
}
}
Note, the project should build at this point.
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_5dab075c-740b-41a8-aa8a-1f82ab58c0be.png)
Create a OData4Controllers folder in the Controllers folder and add a OData4Controller.cs file using the following code:
using Angular2QuickStart.Models;
using System;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.OData;
using System.Web.OData.Routing;
namespace Angular2QuickStart.Controllers
{
public class OData4Controller : ODataController
{
#region public IHttpActionResult CurrentUser()
// odata/CurrentUser() - must be a Post call
[ODataRoute("CurrentUser()")]
public IHttpActionResult CurrentUser()
{
// User to return
User objUser = new User();
// See if the user is logged in
if (this.User.Identity.IsAuthenticated)
{
// They are logged in
objUser.UserName = this.User.Identity.Name;
}
else
{
// They are not logged in
objUser.UserName = "[Not Logged in]";
}
// Return the result
return Ok(objUser);
}
#endregion
}
}
This will provides the OData method that was configured in the WebApiConfig class.
This method will be called by the Angular code.
Add the Angular Code
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_5551b97e-04d6-43ed-98a4-df4290443ea8.png)
Create a user folder under the app folder and create a user.ts file using the following code:
/* Defines the user entity */
export interface IUser {
UserName: string;
}
This interface will define the class that will be used to display the user.
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_e9c37619-fc39-4954-8065-ab5b02c97840.png)
Create a user.service.ts file using the following code:
import { Injectable } from '@angular/core';
import { Http, Response, RequestOptions, Request, RequestMethod, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import { IUser } from './user';
@Injectable()
export class UserService {
private _userUrl = 'odata/CurrentUser';
constructor(private _http: Http) { }
getCurrentUser(): Observable<IUser> {
// This is a Post so we have to pass Headers
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
// Make the Angular 2 Post
// In this case we are not passing any parameters
// so the { } has nothing inside
return this._http.post(this._userUrl, { }, options)
.map((response: Response) => <IUser[]>response.json())
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
private handleError(error: Response) {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
This is a service that will be consumed by the component that will be shown next.
Note that that OData method being called requires a http Post rather than the usual http Get.
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_d4b4af3a-4c77-4631-a236-abfc3317dce3.png)
Create a user.component.ts file using the following code:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
import { IUser } from './user';
import { UserService } from './user.service';
@Component({
selector: 'user-detail',
templateUrl: 'app/user/user.component.html'
})
export class UserComponent implements OnInit {
pageTitle: string = 'Current User';
user: IUser;
errorMessage: string;
// Register the service
constructor(private _userService: UserService) {
}
ngOnInit(): void {
// Call the method that will call the service
this.getCurrentUser();
}
getCurrentUser() {
// Call the service
this._userService.getCurrentUser().subscribe(
user => this.user = user,
error => this.errorMessage = <any>error);
}
}
This is the Angular 2 component that will be consumed in the application’s main component.
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_83e8590b-cccc-4148-9cea-ad8e9d30f731.png)
Now, create a user.component.html file using the following code:
<div class='panel panel-primary' *ngIf='user'>
<div class='panel-heading' style='font-size:large'>
{{pageTitle + ': ' + user.UserName}}
</div>
</div>
This is the template that the component needs to display the data.
Note, that *ngIf=’user is used so that the Div does not display until the user object contains data.
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_95860036-515b-4794-a04f-146ffebd05fa.png)
We created new components and services and their dependencies, and they need to registered in the main module.
Open the app.module.ts file and replace all the code with the following code:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { UserService } from './user/user.service';
import { AppComponent } from './app.component';
import { UserComponent } from './user/user.component';
@NgModule({
imports: [
BrowserModule,
HttpModule
],
declarations: [
AppComponent,
UserComponent
],
providers: [
UserService
],
bootstrap: [
AppComponent
]
})
export class AppModule { }
![image image](/Portals/0/Blog/Files/1/3294/Windows-Live-Writer-c668c2851f28_7AC2-image_4e8c57cd-f9ba-469b-a71f-52524bdee25d.png)
Finally, open the app.component.ts file and add the following code to the end of the template:
<user-detail>Loading...</user-detail>
So that the complete code for the file reads as follows:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>Hello World!</h1>
<h2>{{DynamicValue}}</h2>
<user-detail>Loading...</user-detail>
`
})
export class AppComponent {
DynamicValue: string =
"Running on IIS with ASP.NET 4.5 in Visual Studio 2015";
}
Links
Angular 2+ Logging Into An ASP.NET 4.5 Application
Implement ASP.NET 4 MVC Application Security in Angular 2 Using OData 4
Angular 2 Visual Studio 2015 QuickStart
Download Visual Studio 2015 Community Edition (Free)
Resources to Learn Angular 2
Angular 2: Getting Started (Pluralsight – Paid)
Introduction to Angular 2.0 (Microsoft Virtual Academy – Free)
Download
The project is available at http://lightswitchhelpwebsite.com/Downloads.aspx
You must have Visual Studio 2015 Update 3 (or higher) and TypeScript 2.0 (or higher) installed to run the code.
2 comment(s) so far...
Dear,
im using cookies based authentication my asp api & angular application is separate and this is my mvc authentication
FormsAuthentication.SetAuthCookie(ls_user, false); var authTicket = new FormsAuthenticationTicket(1, ls_user, DateTime.Now, DateTime.Now.AddMinutes(20), false, "Admin"); string encryptedTicket = FormsAuthentication.Encrypt(authTicket); var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);
-------------------------------------
after login i get a Cookie: .ASPXAUTH=AC9....... how do i set this cookie in my http request header ? Please give me the sample syntax for setting header with ASPXAUTH or is there any way to use same session for all http requests for angular ?
By shijil on
11/4/2017 7:29 AM
|
@shijil - Sorry I have no examples.
By Michael Washington on
11/4/2017 7:30 AM
|