Git Product home page Git Product logo

asp.net-core-2-and-angular-5's Introduction

ASP.NET Core 2 and Angular 5

This is the code repository for ASP.NET Core 2 and Angular 5, published by Packt. It contains all the supporting project files necessary to work through the book from start to finish.

IMPORTANT NOTE

If you experience any issue while running the project while following the book's Chapter 01, please do the following:

  • Get the updated project from GitHub and save it in a separate folder
  • Right-click to the TestMakerFreeWebApp_Chapter_01_Part02 project and Set as StartUp Project
  • Execute the npm-update.bat and update-webpack.bat files
  • Launch the project in debug mode In case it works, compare your code with the GitHub files to see what's wrong. Also be sure to check out the book's errata and other useful info regarding the source code from the Issues page.

About the Book

Full-Stack Web Development means being able to work on both the front-end and back-end portions of an application. Front-end is the part the user will see or interact with, while back-end is the underlying engine which handles the logical flow: server configuration, data storage and retrieval, database interactions, user authentication and more. This book will guide the reader to become proficient, if not fluent, in both of these worlds by combining the impressive capabilities of ASP.NET Core 2 and Angular 5. Get ready to experience a journey of the entire development process using a full-stack approach, from the project setup to the deployment phase: using the ASP.NET MVC Framework to implement the back-end API calls, Entity Framework Core to build the Data Model, then Angular 5 to put together the front-end. You'll be able to take full control of your solution by choosing and configuring the development tools accordingly along with the main architecture. You will then implement the back-end with MVC, APIs, server-side routing and request-response cycle and also implement the front-end with Angular 5. Later on, you will build the Data Model with Entity Framework Core and style the front-end with Bootstrap and CSS/LESS for a responsive, mobile-friendly UI. You will go through Forms and Validation and different Authentication and Authorization techniques, including Third-Party Authentication using OAuth2 providers such as Facebook. At the end, you will go through the final steps of Deployment using Windows Server, SQL Server, and the IIS/Kestrel reverse proxy.

Instructions and Navigation

All of the code is organized into folders. Each folder starts with a number followed by the application name. For example, Chapter02.

The code will look like the following:

import { Component } from "@angular/core";

@Component({
    selector: "pagenotfound",
    templateUrl: "./pagenotfound.component.html"
})

export class PageNotFoundComponent {
    title = "Page not Found";
}

Related Products

Download a free PDF

If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.

https://packt.link/free-ebook/9781788293600

asp.net-core-2-and-angular-5's People

Contributors

darkseal avatar dominicpereira92 avatar hk021 avatar packt-itservice avatar packtutkarshr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

asp.net-core-2-and-angular-5's Issues

ERROR in ./node_modules/bootstrap/dist/js/bootstrap.js Module not found: Error: Can't resolve 'popper.js'

Hello, When I start Chapter 3 page 113 Testing up, I receive the following errors:

ERROR in ./node_modules/bootstrap/dist/js/bootstrap.js
Module not found: Error: Can't resolve 'popper.js' in 'D:\MVC\TestMakerFree\TestMakerFreeWebApp\node_modules\bootstrap\dist\js'
@ ./node_modules/bootstrap/dist/js/bootstrap.js 7:100-120
@ ./ClientApp/boot.browser.ts
@ multi event-source-polyfill webpack-hot-middleware/client?path=__webpack_hmr&dynamicPublicPath=true ./ClientApp/boot.browser.ts

ERROR in ./ClientApp/boot.browser.ts
Module not found: Error: Can't resolve 'zone.js' in 'D:\MVC\TestMakerFree\TestMakerFreeWebApp\ClientApp'
@ ./ClientApp/boot.browser.ts 2:0-17
@ multi event-source-polyfill webpack-hot-middleware/client?path=__webpack_hmr&dynamicPublicPath=true ./ClientApp/boot.browser.ts

ERROR in [at-loader] ./ClientApp/app/components/quiz/quiz-list.component.ts:10:5
TS2564: Property 'selectedQuiz' has no initializer and is not definitely assigned in the constructor.
ERROR in [at-loader] ./ClientApp/app/components/quiz/quiz-list.component.ts:11:5
TS2564: Property 'quizzes' has no initializer and is not definitely assigned in the constructor.
ERROR in [at-loader] ./ClientApp/app/components/quiz/quiz-list.component.ts:15:14
TS2339: Property 'http' does not exist on type 'QuizListComponent'.
ERROR in [at-loader] ./ClientApp/app/components/quiz/quiz-list.component.ts:15:46
TS7006: Parameter 'result' implicitly has an 'any' type.
ERROR in [at-loader] ./ClientApp/app/components/quiz/quiz-list.component.ts:15:83
TS7006: Parameter 'error' implicitly has an 'any' type.

Can you help me. Thank you in advance.

Clarification: meaning of LastModifiedDate

Hi,

Just to make sure:

  • CreatedDate is meant to be the date and time at which a Quiz was created?
  • LastModifiedDate is meant to be the date and time at which a Quiz was modified for the last time?

If these are true, then when you update a Quiz (Quiz Controler, Post Method, related to issue #17 ) do you set the LastModifiedDate to the CreatedDate? (see code below)

// properties set from server-side

quiz.LastModifiedDate = quiz.CreatedDate;

Shouldn't it be more like the following?

// properties set from server-side

quiz.LastModifiedDate = DateTime.Now;

About lazy-loading

Microsoft docs say that the lazy-loading feature was introduced in EF Core 2.1.
But the application in this book uses EF Core 2.0.
So will lazy-loading work if I want to load related entities?

p272 - Less nested selector

At page 272, you can read the following.

// the & char represents the current selector parent .
// in this scenario, it stands for item-list.latest .

Shouldn't it be quiz-list.latest instead of item-list.latest?

Impossible to Create First Project

I'm sorry to bother you but I tried to re-create your steps and after 5 hours here, I can't make this thing work! I had to come to your files and even, when I did run your project, it came to an error... I'm frustrated... I think I did take care of each step carefully... tried to use the latest versions, bad! tried to use your version, bad! tried and tried and tried!
screenshot1

I need some help, otherwise I will drop this book and claim my money back... I understand that you cant edit the pdf file or the physical book BUT at least you should have an updated video or step by step on how to start a project from 0, then update angular 4 to 5... because the only way I was able to make it work is by taking your code and run the 2 .bat files you have there... but I would like to know how to do it from scratch... I tried to run the command npm update also with no success... how did you make this work???

Can't manage to user Role Authorization filter on controllers method

Hi @Darkseal , thanks for the support in the beginning, i got the same issue as MammadK, i cant manage how to add roles based filter upon the contollers for role based authorization.
Let me explain a little better, for me is working fine the [Authorized] filter but not the [Authorized(Roles="Administrator")] i got the DB seeded right as you can see in the screen shots.
In the book i m greatly guided throught the creation of the registeredUser and the Administrator roles but after does't explain how to get use of those roles for protecting apps API! am i missing something. i really need this!
users
usertoroles
roles

as MammadK says i tried to retrive information about the user in as an example the quiz controller here there i a screen shot and everything seems working fine here is the pic.
gettingtheusersandroles

Also i got one last question, roaming around the internet in the various stackoverflow or blogs i find that everyone is putting the policy or role data in the jwt token and then in the startup class somehow setting the built in authorize class to manage policy or roles, but instead can i in someway get the roles of the user based on his Id on the DB? so somehow i can get the roles of the user on the fly and check for right authorization role so i don t have to expose roles of the user to the public?
Well thanks for everything, hope i wrote something understandable!

this._subscribe is not a function

Hi,
I get an error (this._subscribe is not a function) when the token tries to refresh and then, it seems the script makes an infinite loop.
This happens within the auth.response.interceptor.ts file.
any idea?

 this.auth.refreshToken()
                    .subscribe(res => {
                    if (res) {
                        // refresh token successful
                        console.log("refresh token successful");

                        // re-submit the failed request
                        var http = this.injector.get(HttpClient);
                        http.request(this.currentRequest).subscribe(
                            (result:any) => {

                            }, (error:any) => console.error(error)
                        );
                    }
                    else {
                        // refresh token failed
                        console.log("refresh token failed");

                        // erase current token
                        this.auth.logout();

                        // redirect to login page
                        this.router.navigate(["login"]);
                    }
                }, error => console.log(error));

Build Errors

When I try to Build 'TestMakerFreeWebApp_UpdatedProject' I get the following errors:

Can't resolve 'bootswatch/flatly/bootstrap.css' in 'C:\code\TestMaker\TestMakerFreeWebApp_UpdatedProject'

and

MSB3073 The command "node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js" exited with code 2.

Can you please advise how I can fix this issue. Thanks.

Quiz-list-component issue

I am experiencing a problem with the quiz list. It does not seem to like either one of the following:

import { HttpClient } from '@angular/common/http';
to
import { HttpClientModule } from '@angular/common/http';

I get a build error for both. Went to the Google docs and it looks like the bottom is correct. But I am still getting errors. Appreciate a solution so I can continue.

Forgot password & remember me

In the section of the book that covers Login implementation, the text states:

"To be completely honest, the Remember me and Forgot the password? functions are not working yet, but we'll fix those in due time."

However I don't see anywhere in the book where these features are covered. Am I missing something?

Chapter_09 - Refresh Token loop

Hi,
I´am running the code of chapter_09 and get an infinite loop of requests while testing the refresh token "feature".

console

Maybe there is something wrong/missing within the AuthResponseInterceptor ?

Logo.svg => Location / Configuration

Hi, really basic here. In the book you mention adding logo.svg. The book only mentions pulling the one that was created but not where to put it in the project.

The sample solutions do not have this logo in them. Where should this logo be placed so that it gets propagated into the built application?

The image source in the app.component.html file referenced ./dist/res/img/logo.svg so that's where I put it. Obviously, I don't think WebPack knows to build/copy it over to the final wwwroot.

Where should it go and what needs to be configured to copy it into the final site build?

Thanks.

quiz-list.component.ts

With code from the repository I can reproduce the error on any chapter. The four lines starting at @input are the lines with the errors.

Visual Studio Community 2017

export class QuizListComponent implements OnInit {

@Input() class: string;

title: string;

selectedQuiz: Quiz;

quizzes: Quiz[];

Severity Code Description Project File Line Suppression State
Error TS2564 (TS) Property 'class' has no initializer and is not definitely assigned in the constructor. TestMakerFreeWebApp_Chapter_02 (tsconfig project) C:\Users\JWPok\source\repos\Core2angular5\ASP.NET-Core-2-and-Angular-5-master\TestMakerFreeWebApp_Chapter_02\ClientApp\app\components\quiz\quiz-list.component.ts 23 Active

Error TS2564 (TS) Property 'quizzes' has no initializer and is not definitely assigned in the constructor. TestMakerFreeWebApp_Chapter_02 (tsconfig project) C:\Users\JWPok\source\repos\Core2angular5\ASP.NET-Core-2-and-Angular-5-master\TestMakerFreeWebApp_Chapter_02\ClientApp\app\components\quiz\quiz-list.component.ts 29 Active

Error TS2564 (TS) Property 'selectedQuiz' has no initializer and is not definitely assigned in the constructor. TestMakerFreeWebApp_Chapter_02 (tsconfig project) C:\Users\JWPok\source\repos\Core2angular5\ASP.NET-Core-2-and-Angular-5-master\TestMakerFreeWebApp_Chapter_02\ClientApp\app\components\quiz\quiz-list.component.ts 27 Active

Error TS2564 (TS) Property 'title' has no initializer and is not definitely assigned in the constructor. TestMakerFreeWebApp_Chapter_02 (tsconfig project) C:\Users\JWPok\source\repos\Core2angular5\ASP.NET-Core-2-and-Angular-5-master\TestMakerFreeWebApp_Chapter_02\ClientApp\app\components\quiz\quiz-list.component.ts 25 Active

Identity roles doesn't work

hello
I want to use "Role" for "Authorize" in Controller like this
[Authorize(Roles = "Administrator")]
but it doesn't work.
also when i use this code:
ApplicationUser user=UserManager.FindByEmailAsync("[email protected]").Result;
var roles = UserManager.GetRolesAsync(user);
roles return "null".
i need to use it.
please help me.
thank you.

Publish doesn't work.

When Trying to publish the project in Visual Studio 2017, it gives the following error:

Error: Can't resolve 'bootswatch/flatly/bootstrap.css' in 'C:\Projects\TestMakerFree' TestMakerFree Module not found 0

Error: The command "node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" exited with code 2. TestMakerFree C:\Projects\TestMakerFree\TestMakerFree.csproj 70

I cannot find where it points to 'bootswatch/flatly/bootstrap.css'

Angular CLI version

Hi,

I had took a walk around the Angular tendances on the net, and found that the way this project is made exposes to many limits since it is not using Angular CLI, most people exposing projects on github or other sites had enhanced their projects to use Angular CLI instead of Webpack.

I think it is time to do the same with this course, or at least publish simultaneously a second version using Angular CLI.

"The broken code myth"

This is a great book, very readable. But the code in the book isn't the same as what's on github. For example, I'm in Chapter 3, page 116: Testing it up. The wrong controller method was being hit. Get, and not Latest.

So I compare the code I typed in from the book, with what's on github.

The route for Latest in the book:
[HttpGet("Latest/{num}")]

The route for Latest on github:
[HttpGet("Latest/{num:int?}")]

And sure enough that's enough to break the code.

So, it's no myth. The code is broken. Thank you for fixing it in github, but I would rather not type everything in, then have it break, only to then chase down the corrected code on github.

Could you maybe publish a list, chapter by chapter, of code that diverges from what's in the book?

Thanks, and sorry if I'm being a jerk. I really do love the book so far, and I'm learning a ton.

Aaron

The New User Registration is not working

Hello,
Git cloned the code from here, then used only the finished project, followed the new book instructions, and then run the initial migrations using the command below from an admin powershell window:

dotnet ef migrations add "Initial" -o "Data\Migrations"

Got error: An error occurred while calling method 'BuildWebHost' on class 'Program'. Continuing without the application service provider. Error: Invalid object name 'Users'.

Then executed dotnet ef database update

And got the database tables and the sample data. The 4 default users and related stuff are there.

I ensured I can login normally, but when I click to add a new user in the register form, nothing happens and the browser ( Chrome ) console shows the following message:

HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "http://localhost:14600/api/user", ok: false, …}
error

SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse (<anonymous>) at XMLHttpRequest.onLoad (http://localhost:14600/dist/main-client.js?


Then Trying to send the request using Postman

{
"username":"User1",
"password":"Pass4User1",
"Email":"[email protected]",
"DisplayName":"User1"
}

I get the 500 Internal server error,  with the  next header:

SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_AspNetUserRoles_Users_UserId". The conflict occurred in database "DataBaseName", table "dbo.Users", column 'Id'.
 The statement has been terminated.

I checked and compared the FOREIGN KEY constraint "FK_AspNetUserRoles_Users_UserId" with another working database and found they are same, so I guess the code doesn't provide a default role to the registering user.

QuizComponent overlaps navigation bar menu

Hi guys!!. Thanks for this amazing book, it's really enjoyable.
I've found an issue with the navigation bar. When I select a quiz and then click on the navigation bar button to expand the menu, this is displayed behind the quiz picture and I can't select any item. See the attached image. Thanks!!!
navbar_issue

Breakpoint will not currently be hit. No symbols loaded for this document (TS code)

I'm trying to take advantage of the TypeScript runtime debugging capabilities
provided by Visual Studio 2017, as shown in page 124 of the book. But after I start debugging, it shows me on the breakpoint the message:
Breakpoint will not currently be hit. No symbols loaded for this document
and it does not stop at the breakpoint.

Can you help me? Thank you in advance.

UpdatedProject --Can't generate default database

The code breaks at this line in DbSeeder.
if (!dbContext.Users.Any())

I tried to call SetInitializer() in ApplicationDbContext constructor, but I can't find this method any more.
Did I miss anything else?

Thanks,
Bruce

Chapter 7 Answer Validator Work but Dont show error message

following the steps to validate answer-edit.html and answer-edit.component.ts
the validation work only that the form is empty dont show the error message lake the page 339 .

this are my files

answer-edit.component.html

<h2>{{title}}</h2>
<div class="answer-edit">
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
        <div class="form-group"
             [ngClass]="{ 'has-error has-feedback' : hasError('Text') }">
            <label for="text">Answer text:</label>
            <br />
            <textarea id="text"
                      formControlName="Text" required
                      placeholder="enter a suitable text..."
                      class="form-control"></textarea>
            <span *ngIf="hasError('Text')"
                  class="glyphicon glyphicon-remove form-control-feedback"
                  aria-hidden="true"></span>
            <div *ngIf="hasError('Text')"
                 class="help-block">
                Text is a required field: please insert a valid text.
            </div>
        </div>

        <div class="form-group"
             [ngClass]="{ 'has-error has-feedback' : hasError('Value') }">
            <label for="value">Score Value:</label>
            <br />
            <select id="value"
                    formControlName="Value" required
                    class="form-control">
                <option value="">Pick a value...</option>
                <option *ngFor="let num of [-5,-4,-3,-2,-1,0,1,2,3,4,5]"
                        [value]="num">
                    {{num}}
                </option>
            </select>
            <div *ngIf="hasError('Value')"
                 class="help-block">
                Please select a valid number between -5 and 5.
            </div>
        </div>
        <div class="form-group commands">
            <button *ngIf="editMode" type="submit"
                    [disabled]="form.invalid"
                    class="btn btn-success">
                Apply Changes
            </button>
            <button *ngIf="!editMode" type="submit"
                    [disabled]="form.invalid"
                    class="btn btn-success">
                Create the Answer!
            </button>
            <button type="submit"
                    (click)="onBack()"
                    class="btn btn-default">
                Cancel
            </button>
        </div>
    </form>
</div>

this is my answer-edit.component.ts

import { Component, Inject, OnInit } from "@angular/core";
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from "@angular/router";
import { HttpClient } from "@angular/common/http";

@Component({
    selector: "answer-edit",
    templateUrl: './answer-edit.component.html',
    styleUrls: ['./answer-edit.component.css']
})

export class AnswerEditComponent {
    title: string;
    answer: Answer;
    form: FormGroup;

    // this will be TRUE when editing an existing question, 
    //   FALSE when creating a new one.
    editMode: boolean;

    constructor(private activatedRoute: ActivatedRoute,
        private router: Router,
        private http: HttpClient,
        private fb: FormBuilder,
        @Inject('BASE_URL') private baseUrl: string) {

        // create an empty object from the Quiz interface
        this.answer = <Answer>{};

        // initialize the form
        this.createForm();

        var id = +this.activatedRoute.snapshot.params["id"];

        // quick & dirty way to check if we're in edit mode or not
        this.editMode = (this.activatedRoute.snapshot.url[1].path == "edit");

        if (this.editMode) {

            // fetch the answer from the server
            var url = this.baseUrl + "api/answer/" + id;
            this.http.get<Answer>(url).subscribe(result => {
                this.answer = result;
                this.title = "Edit - " + this.answer.Text;

                // update the form with the question value
                this.updateForm();

            }, error => console.error(error));
        }
        else {
            this.answer.QuestionId = id;
            this.title = "Create a new Answer";
        }
    }

    createForm() {
        this.form = this.fb.group({
            Text: ['', Validators.required],
            Value: ['',
                [Validators.required,
                Validators.min(-5),
                Validators.max(5)]
            ]
        });
    }

    updateForm() {
        this.form.setValue({
            Text: this.answer.Text || '',
            Value: this.answer.Value || 0
        });
    }

    onSubmit() {
        // build a temporary answer object from form values
        var tempAnswer = <Answer>{};
        tempAnswer.Text = this.form.value.Text;
        tempAnswer.Value = this.form.value.Value;
        tempAnswer.QuestionId = this.answer.QuestionId;

        var url = this.baseUrl + "api/answer";

        if (this.editMode) {
            this.http
                .post<Answer>(url, tempAnswer)
                .subscribe(res => {
                    var v = res;
                    console.log("Answer " + v.Id + " has been updated.");
                    this.router.navigate(["question/edit", v.QuestionId]);
                }, error => console.log(error));
        }
        else {
            this.http
                .put<Answer>(url, tempAnswer)
                .subscribe(res => {
                    var v = res;
                    console.log("Answer " + v.Id + " has been created.");
                    this.router.navigate(["question/edit", v.QuestionId]);
                }, error => console.log(error));
        }
    }

    onBack() {
        this.router.navigate(["question/edit", this.answer.QuestionId]);
    }

    // retrieve a FormControl
    getFormControl(name: string) {
        return this.form.get(name);
    }

    // returns TRUE if the FormControl is valid
    isValid(name: string) {
        var e = this.getFormControl(name);
        return e && e.valid;
    }

    // returns TRUE if the FormControl has been changed
    isChanged(name: string) {
        var e = this.getFormControl(name);
        return e && (e.dirty || e.touched);
    }

    // returns TRUE if the FormControl is invalid after user changes
    hasError(name: string) {
        var e = this.getFormControl(name);
    }
}

and my interface

interface Answer {
    Id: number;
    QuestionId: number;
    Text: string;
    Value?: number; 
}

I do not know what can be happening to me and I have already got question and quiz edit components
working.

Chapter 4 Error

I am getting an error running the Chapter 4 Example code when I run the following command in PowerShell:
dotnet ef migrations add "Initial" -o "Data\Migrations"

Resulting Error:
An error occurred while calling method 'BuildWebHost' on class 'Program'. Continuing without the application service provider. Error: Invalid object name 'Users'.
Unable to create an object of type 'ApplicationDbContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.

With the Error, the result is that the TestMakerFree Database is created with a single table:
dbo._EFMigrationsHistory

Please advise.

Updating the Webpack.config.js file

In my Kindle Reader (browser) version (Chrome)

In the code listing for change from Angular 4 => Angular 5, there is a missing closing curly bracket/brace after the closing of the RegEx ("$/"):

This:
{ test: /(?:.ngfactory.js|.ngstyle.js|.ts)$/,

Should be:
{ test: /(?:.ngfactory.js|.ngstyle.js|.ts)$/ },

Hope this helps!

Jon

Chapter 9 auth.response.interceptor does not work correctly when multiple requests are done nearly at the same time

If the cookie has timed out, your interceptor works well if the next API call is a single request. But, for example, if I open a component that needs a lot of API calls, for example to fill 10 dropdown lists, then the app will make 10 API calls nearly at the same time. In this case, the way you store the current request is not good. Indeed, the 10 firsts API request will come back on error, then 10 calls will be made to get a refresh token, and then the reexecuted calls will mostly be the refresh token call and not the original API calls.
If you store the current request, not in the authinterceptor itself (currentRequest: HttpRequest),
but in the intercept method (let currentRequest: HttpRequest = request.clone();). And then pass the request to the handleError (handleError(err: any, next: HttpHandler, request: HttpRequest)).
Then everything works fine and all the original API calls are correctly called again.
Regards,
PS : thank you for your books that greatly help me!

Code sample (modifications commented //XXXXXXXXXXX)

@Injectable()
export class AuthResponseInterceptor implements HttpInterceptor {
  auth: AuthService;
  constructor(
    private injector: Injector,
    private router: Router,
    private applicationUserContext: ApplicationUserContext
    , public dialog: MatDialog
  ) { }

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler): Observable<HttpEvent<any>> {

    this.auth = this.injector.get(AuthService);
    var token = (this.auth.isLoggedIn()) ? this.auth.getAuth()!.token : null;

    if (token) {
      // save current request
      let currentRequest: HttpRequest<any> = request.clone(); //XXXXXXXXXXX

      return next.handle(request).pipe(
        tap((event: HttpEvent<any>) => {
          if (event instanceof HttpResponse) {
            // do nothing
          }
        }),
        catchError(error => {
          return this.handleError(error, next, currentRequest) //XXXXXXXXXXX
        }));
    }
    else {
      return next.handle(request);
    }
  }

  handleError(err: any, next: HttpHandler, request: HttpRequest<any>) {  //XXXXXXXXXXX
    if (err instanceof HttpErrorResponse) {
      if (err.status === 403) {
        // JWT token might be expired if the error does not come from a new token request
        if (err.url.endsWith("evapi/token/auth")) {
          //Close all existing dialog
          this.dialog.closeAll();
          //Show error
          showErrorToUser(this.dialog, err, this.applicationUserContext);
          //Route to login
          this.router.navigate(["login"]);
        }
        else {
          // try to get a new one using refresh token
          let previousRequest = request;  //XXXXXXXXXXX
          return this.auth.refreshToken().pipe(
            flatMap((refreshed) => {
              var token = (this.auth.isLoggedIn()) ? this.auth.getAuth()!.token : null;
              if (token) {
                previousRequest = previousRequest.clone({
                  setHeaders: { eValorplastSecurity: token }
                });
              }
              return next.handle(previousRequest);
            }));
        }
      }
      if (err.status === 401) {
        //Forbidden
        this.router.navigate(["forbidden"]);
      }
    }
    return throwError(err);
  }
}

Validation of the registration form

A more logical solution to some problems (errors during registration) can be solved by adding checks during registration. It is necessary somehow to validate the given parameters (in file Startup.cs):

opts.Password.RequireDigit = true;
opts.Password.RequireLowercase = true;
opts.Password.RequireUppercase = true;
opts.Password.RequireNonAlphanumeric = false;
opts.Password.RequiredLength = 7;

Missing change of bootstrap class in book

In all references of the navmenu.component.html, in the div of the navbar, the book points to the following class: navbar-inverse. But, starting in the page 296 of chapter 6, the component changed the color to dark blue. I found that the class responsible for this is the navbar-default, but at no time quoted in the book.

Maybe this issue can help someone, with the same problem.

Chapter 9 Async Refresh Token

When I make more than one async request to the backend and token is expired I get an error 401 for each request, this causes the creation of a token per request in the table because a request follows the previous one.

There is some way to control this behavior?

Bootstrap 4 and Error: Can't resolve 'bootswatch/flatly/bootstrap.css'

Hello,
I edited package.json to update bootstrap and bootswatch to the latest stable versions (respectively 4.1.0 and 4.0.0) but now when I try to run update-webpack.bat I get the following error:

ERROR in dll vendor
    Module not found: Error: Can't resolve 'bootswatch/flatly/bootstrap.css'

Is there something else I need to change to make it work?
Thank you.

Usage of Put and Post

It seems that in this book Put is used to create a new item and Post to update an existing one. From my knowledge on HTTP, shouldnt Post be used to create a new item and Put to create if doesn't exist/ update if exists? Is the reverse usage simply a preference of the author or is there more meaning behind it?

Use Angular Material and Angular 5 in VS 2017

Good afternoon! Make a short article - the instructions for working with Angular Material in VS 2017. I use the official documentation - I can not display a simple button. I have been looking for two weeks on the Internet

self.authService.setAuth doesn't set Auth after External Login successful

In Chapter 9, Explicit Flow implementation of the OAuth2, After a successful login of the facebook, and redirecting to the home page, I would expect the user is being Logged-In and the token is set. But unfortunately it seems this line is not working self.authService.setAuth(auth); and so the token is not generated.


export class LoginExternalProvidersComponent implements OnInit {
  externalProviderWindow: any;
  constructor(
    private http: HttpClient,
    private router: Router,
    private authService: AuthService,
    // inject the local zone
    private zone: NgZone,
    @Inject(PLATFORM_ID) private platformId: any, @Inject('BASE_URL') private baseUrl: string) {
  }
  ngOnInit() {
    if (!isPlatformBrowser(this.platformId)) {
      return;
    }
    // close previously opened windows (if any)
    this.closePopUpWindow();
    // instantiate the externalProviderLogin function
    // (if it doesn't exist already)
    var self = this;
    if (!window.externalProviderLogin) {
      window.externalProviderLogin = function (auth: ITokenResponse) {
        self.zone.run(() => {
          console.log("External Login successful!");
          self.authService.setAuth(auth);
          self.router.navigate([""]);
        });
      }
    }
  }

closePopUpWindow() {
    if (this.externalProviderWindow) {
        this.externalProviderWindow.close();
    }
    this.externalProviderWindow = null;
  }

callExternalLogin(providerName: string) {
    if (!isPlatformBrowser(this.platformId)) {
    return;
    }
var url = this.baseUrl + "api/Token/ExternalLogin/" + providerName;
// minimalistic mobile devices support
var w = (screen.width >= 1050) ? 1050 : screen.width;
var h = (screen.height >= 550) ? 550 : screen.height;
var params = "toolbar=yes,scrollbars=yes,resizable=yes,width="
+ w + ", height=" + h;
// close previously opened windows (if any)
this.closePopUpWindow();
  this.externalProviderWindow = window.open(url, "ExternalProvider", params, false);
  }
}

Chapter_05_Part01 - Error on deleting quiz

Hello,

there is a problem when deleting a quiz:

capturar

The quiz is deleted, but remains in the same route.

seems that the problem is in the return of the quizcontroller delete action:

return new OkResult();

if we change to :

return new NoContentResult()

it fix the problem.

Issue refreshing a page after authenticating

Hi,

I'll admit, I haven't followed the entire book as I'm currently using it to implement token authentication in Angular 5, so my code isn't identical to the GitHub book.

Currently I can log in and authenticate on my app which makes a request to a controller decorated with [Authorize]. However, if I refresh this Angular page, I then get:

image

If I check my console, I can see:

fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
      An unhandled exception has occurred: Http failure response for http://localhost:5001/api/SampleData/GetTests: 401 Unauthorized

Microsoft.AspNetCore.NodeServices.HostingModels.NodeInvocationException: Http failure response for http://localhost:5001/api/SampleData/GetTests: 401 Unauthorized

I have checked my headers and for some reason, on refresh of the page the token is not set in the header (the interceptor isn't hit at all).

However, if I go back to the app's home page and click back in to the page that requires authentication, everything works fine again.

Is this to do with the SSR bugs in Angular 5 / Core? Or have I done something else wrong.

Disabling SSR makes all these issues disappear, but it would be nice to find out what's going on and see if it's possible to fix

Thanks

Why Have a Type Property in Token Table?

Hi

I am a bit confused on why you have a property called "Type" in your token class. All the book says is

There's nothing new here, just the minimum amount of properties to store the relevant information about the token: the ClientId, where it comes from, its Type(we'll use a value of zero for refresh tokens), its Value, the UserId it was issued to, and the creation date.

What other types other than a refresh token would be stored in this table?

Chapter_09 - After fixing Refresh Token loop

Hello,
I applied the fix suggested at #8 to get rid of the loop. That took care of the infinite loop; I don't see any errors being logged in the console anymore. The problem I see now when I follow the steps mentioned under "Testing it up" on page 833 is that, after clicking the "Apply Changes" button and making the call to the API to update the quiz, the user is not redirected to the Home page as he should. The html rendered by the quiz-edit.component.html file remains on the screen with the focus set on the "Apply Changes" button.

Logic error in Chapter 7

In the result.edit.component.ts file, you have the following lines in the updateForm() function:

MinValue: this.result.MinValue || '',
MaxValue: this.result.MaxValue || ''

The problem here is that when MinValue or MaxValue is 0, the form input is populated with the empty string.

This is because the integer 0 is "falsy" is JavaScript, and thus when either value is 0, the corresponding expression evaluates to ''. Thus '' is what ends up in the form, not 0.

This should actually be:

MinValue: this.result.MinValue,
MaxValue: this.result.MaxValue

That way, if the value is null, an empty string is populated into the form. And if the value is 0, a 0 appears in the form.

Thought you'd like to know.

Test code breaks Chap1 example

I've found that removing the following file fixes the Chap01_Part01 example project for me...

ASP.NET-Core-2-and-Angular-5/TestMakerFreeWebApp_Chapter_01_Part01/ClientApp/app/components/counter/counter.component.ts

Initially, I received errors launching the site from this project. Erroneous unit tests?

NgFor only supports binding to Iterables such as Arrays

I have a problem in Chapter 03 when trying to iterate the sample quiz on the home page. My component look like this:

`
import { Component, Inject, OnInit } from "'@'angular/core";
import { HttpClient } from "'@'angular/common/http";

@component({
selector: "quiz-list",
templateUrl: './quiz-list.component.html',
styleUrls: ['./quiz-list.component.css']
})

export class QuizListComponent implements OnInit {
title: string;
selectedQuiz: Quiz;
quizzes: Quiz[];
http: HttpClient;
baseUrl: string;

constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    this.title = "Latest quizzes";
    this.baseUrl = baseUrl + "api/quiz/latest/";
    this.http = http;
}

ngOnInit() {
    this.http.get<Quiz[]>(this.baseUrl).subscribe(result => {
        this.quizzes = result; 
    }, error => console.error(error));
}

onSelect(quiz: Quiz) {
    this.selectedQuiz = quiz;
    
}

}`

And the ngfor below is the problem (i think):

*ngFor="let quiz of quizzes"

The problem is that the ngFor doesnt recognize quizzes as the arraytype Quiz[] that it is. Instead it thinks of it as an undefined object. So the browser gives me this errormessage:

ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

I cant get by this problem because according to the new HttpClient for angular i dont have to parse data since i am setting the type in the get<Quiz[]> method. Anyone had the same problem and solved it?

Chapter_08. An unhandled exception occurred while processing the request.

When you run the code from paragraph 8, an error occurs: "An unhandled exception occurred while processing the request. NodeInvocationException: Prerendering timed out after 30000ms because the boot function in 'ClientApp/dist/main-server' returned a promise that did not resolve or reject. Make sure that your boot function always resolves or rejects its promise. You can change the timeout value using the 'asp-prerender-timeout' tag helper."

It occurs when you directly use the route "http: // localhost: / home", at direct reference on a route: "http: // localhost: / login" there is no error!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.