ASP.NET Core + Angular项目在我尝试运行时出现错误。

huangapple go评论74阅读模式
英文:

ASP.NET Core + Angular project gives me errors when I try to run it

问题

I see that you're facing some issues with your ASP.NET Core and Angular project. It appears that you're encountering Angular-related errors in your project setup.

Here's a summary of the key issues:

  1. You're getting an error related to the use of [formGroup] in your HTML template. This might be due to the missing import of the ReactiveFormsModule in your Angular module. Ensure you import it like this:

    import { ReactiveFormsModule } from '@angular/forms';
    

    And add it to the imports array in your module:

    imports: [
      CommonModule,
      ReactiveFormsModule,
    ],
    
  2. You also have an issue with the use of loginForm in your HTML template. Ensure that you have declared and initialized loginForm in your component, something like this in your login.component.ts:

    import { FormGroup, FormBuilder, Validators } from '@angular/forms';
    
    // Inside your LoginComponent class
    loginForm: FormGroup;
    
    constructor(private formBuilder: FormBuilder) {
      this.loginForm = this.formBuilder.group({
        email: ['', Validators.required], // Example: Add your form controls here
        password: ['', Validators.required],
      });
    }
    
  3. Make sure you have imported and declared your LoginComponent correctly in your module. It seems that you're importing FooterComponent instead of LoginComponent in your login.module.ts.

    Ensure that you have the correct import for LoginComponent and declare it in your module's declarations array.

Please check these issues, and if you encounter any specific errors or have more details to provide, feel free to share them for further assistance.

英文:

I'm trying something new and that would be using ASP.NET Core as my backend while using Angular for the frontend. While the backend was a breeze to configure, the frontend haven't been as close. When I try running the application, I receive the following errors in teh console:

> integrafechado@0.0.0 prestart
> node aspnetcore-https


> integrafechado@0.0.0 start
> run-script-os


> integrafechado@0.0.0 start:windows
> ng serve --port 44488 --ssl --ssl-cert "%APPDATA%\ASP.NET\https\%npm_package_name%.pem" --ssl-key "%APPDATA%\ASP.NET\https\%npm_package_name%.key"


Initial Chunk Files   | Names         |  Raw Size
vendor.js             | vendor        |   3.03 MB |
styles.css, styles.js | styles        | 440.48 kB |
polyfills.js          | polyfills     | 434.76 kB |
main.js               | main          | 181.56 kB |
runtime.js            | runtime       |   6.53 kB |

                      | Initial Total |   4.07 MB

Build at: 2023-06-12T15:15:32.894Z - Hash: bdb0de9435970ca7 - Time: 2757ms

Error: src/api-authorization/login/login.component.html:6:13 - error NG8002: Can't bind to 'formGroup' since it isn't a known property of 'form'.

6             [formGroup]="loginForm"
              ~~~~~~~~~~~~~~~~~~~~~~~

  src/api-authorization/login/login.component.ts:16:15
    16  templateUrl: "./login.component.html",
                     ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component LoginComponent.


Error: src/api-authorization/login/login.component.html:6:26 - error TS2339: Property 'loginForm' does not exist on type 'LoginComponent'.

6             [formGroup]="loginForm"
                           ~~~~~~~~~

  src/api-authorization/login/login.component.ts:16:15
    16  templateUrl: "./login.component.html",
                     ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component LoginComponent.


Error: src/api-authorization/login/login.component.html:7:25 - error TS2341: Property 'login' is private and only accessible within class 'LoginComponent'.

7             (ngSubmit)="login(loginForm.value)"
                          ~~~~~

  src/api-authorization/login/login.component.ts:16:15
    16  templateUrl: "./login.component.html",
                     ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component LoginComponent.


Error: src/api-authorization/login/login.component.html:7:31 - error TS2339: Property 'loginForm' does not exist on type 'LoginComponent'.

7             (ngSubmit)="login(loginForm.value)"
                                ~~~~~~~~~

  src/api-authorization/login/login.component.ts:16:15
    16  templateUrl: "./login.component.html",
                     ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component LoginComponent.


Error: src/api-authorization/login/login.component.html:69:1 - error NG8001: 'app-footer' is not a known element:
1. If 'app-footer' is an Angular component, then verify that it is part of this module.
2. If 'app-footer' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.

69 <app-footer></app-footer>
   ~~~~~~~~~~~~

  src/api-authorization/login/login.component.ts:16:15
    16  templateUrl: "./login.component.html",
                     ~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component LoginComponent.




** Angular Live Development Server is listening on localhost:44488, open your browser on https://localhost:44488/ **


× Failed to compile.

Here's the login.component.html file:

<div class="login-container">
  <div id="container-main" class="login-container-main">
    <label id="login-label" for="login-form" class="login-text">Login</label>
    <div id="container-form" class="login-container-form">
      <form id="login-form"
            [formGroup]="loginForm"
            (ngSubmit)="login(loginForm.value)"
            name="login-form"
            target="self"
            enctype="application/x-www-form-urlencoded"
            class="login-form">
        <div class="login-container-labels">
          <div id="email-label-div" class="login-container1">
            <label id="email-label" for="email-input" class="login-text1">
              E-mail
            </label>
          </div>
          <div id="senha-label-div" class="login-container2">
            <label id="password-label" for="password-input" class="login-text2">
              Senha
            </label>
          </div>
          <div id="register-div" class="login-container3">
            <label id="noregister-label"
                   for="register-button"
                   class="login-text3">
              Não tem conta?
            </label>
            <button id="register-button"
                    name="register-button"
                    type="button"
                    class="login-button Link button">
              Registrar
            </button>
          </div>
        </div>
        <div class="login-container-inputs">
          <div id="email-input-div" class="login-container4">
            <input formControlName="email"
                   type="email"
                   id="email-input"
                   required
                   autofocus
                   placeholder="exemplo@exemplo.com"
                   class="input" />
          </div>
          <div id="senha-input-div" class="login-container5">
            <input formControlName="password"
                   type="password"
                   id="password-input"
                   required
                   minlength="8"
                   placeholder="Sua senha"
                   class="input" />
          </div>
          <div id="login-div" class="login-container6">
            <button type="submit" class="login-button1 button">
              <span class="login-text4">
                <span class="login-text5">Logar</span>
                <br />
              </span>
            </button>
          </div>
        </div>
      </form>
    </div>
  </div>
</div>
<app-footer></app-footer>

login.module.ts:

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { FooterComponent } from "./footer.component";
@NgModule({
	declarations: [
		FooterComponent
	],
	imports: [
		CommonModule
	],
	exports: [
		FooterComponent
	]
})
export class FooterModule { }

login.component.ts:

/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-useless-escape */
/* eslint-disable no-case-declarations */
import { Component, OnInit } from "@angular/core";
import { AuthorizeService, AuthenticationResultStatus } from "../authorize.service";
import { ActivatedRoute, Router } from "@angular/router";
import { BehaviorSubject } from "rxjs";
import { LoginActions, QueryParameterNames, ApplicationPaths, ReturnUrlType } from "../api-authorization.constants";

// The main responsibility of this component is to handle the user's login process.
// This is the starting point for the login process. Any component that needs to authenticate
// a user can simply perform a redirect to this component with a returnUrl query parameter and
// let the component perform the login and return back to the return url.
@Component({
	selector: "app-login",
	templateUrl: "./login.component.html",
	styleUrls: ["./login.component.css"]
})
export class LoginComponent implements OnInit {
	public message = new BehaviorSubject<string | null | undefined>(null);

	constructor(
    private authorizeService: AuthorizeService,
    private activatedRoute: ActivatedRoute,
    private router: Router) { }

	async ngOnInit() {
		const action = this.activatedRoute.snapshot.url[1];
		switch (action.path) {
		case LoginActions.Login:
			await this.login(this.getReturnUrl());
			break;
		case LoginActions.LoginCallback:
			await this.processLoginCallback();
			break;
		case LoginActions.LoginFailed:
			const message = this.activatedRoute.snapshot.queryParamMap.get(QueryParameterNames.Message);
			this.message.next(message);
			break;
		case LoginActions.Profile:
			this.redirectToProfile();
			break;
		case LoginActions.Register:
			this.redirectToRegister();
			break;
		default:
			throw new Error(`Invalid action '${action}'`);
		}
	}


	private async login(returnUrl: string): Promise<void> {
		const state: INavigationState = { returnUrl };
		const result = await this.authorizeService.signIn(state);
		this.message.next(undefined);
		switch (result.status) {
		case AuthenticationResultStatus.Redirect:
			break;
		case AuthenticationResultStatus.Success:
			await this.navigateToReturnUrl(returnUrl);
			break;
		case AuthenticationResultStatus.Fail:
			await this.router.navigate(ApplicationPaths.LoginFailedPathComponents, {
				queryParams: { [QueryParameterNames.Message]: result.message }
			});
			break;
		default:
			throw new Error(`Invalid status result ${(result as any).status}.`);
		}
	}

	private async processLoginCallback(): Promise<void> {
		const url = window.location.href;
		const result = await this.authorizeService.completeSignIn(url);
		switch (result.status) {
		case AuthenticationResultStatus.Redirect:
			// There should not be any redirects as completeSignIn never redirects.
			throw new Error("Should not redirect.");
		case AuthenticationResultStatus.Success:
			await this.navigateToReturnUrl(this.getReturnUrl(result.state));
			break;
		case AuthenticationResultStatus.Fail:
			this.message.next(result.message);
			break;
		}
	}

	private redirectToRegister(): any {
		this.redirectToApiAuthorizationPath(
			`${ApplicationPaths.IdentityRegisterPath}?returnUrl=${encodeURI("/" + ApplicationPaths.Login)}`);
	}

	private redirectToProfile(): void {
		this.redirectToApiAuthorizationPath(ApplicationPaths.IdentityManagePath);
	}

	private async navigateToReturnUrl(returnUrl: string) {
		// It's important that we do a replace here so that we remove the callback uri with the
		// fragment containing the tokens from the browser history.
		await this.router.navigateByUrl(returnUrl, {
			replaceUrl: true
		});
	}

	private getReturnUrl(state?: INavigationState): string {
		const fromQuery = (this.activatedRoute.snapshot.queryParams as INavigationState).returnUrl;
		// If the url is coming from the query string, check that is either
		// a relative url or an absolute url
		if (fromQuery &&
      !(fromQuery.startsWith(`${window.location.origin}/`) ||
        /\/[^\/].*/.test(fromQuery))) {
			// This is an extra check to prevent open redirects.
			throw new Error("Invalid return url. The return url needs to have the same origin as the current page.");
		}
		return (state && state.returnUrl) ||
      fromQuery ||
      ApplicationPaths.DefaultLoginRedirectPath;
	}

	private redirectToApiAuthorizationPath(apiAuthorizationPath: string) {
		// It's important that we do a replace here so that when the user hits the back arrow on the
		// browser they get sent back to where it was on the app instead of to an endpoint on this
		// component.
		const redirectUrl = `${window.location.origin}/${apiAuthorizationPath}`;
		window.location.replace(redirectUrl);
	}
}

interface INavigationState {
  [ReturnUrlType]: string;
}

and finally, footer.module.ts:

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { FooterComponent } from "./footer.component";
@NgModule({
	declarations: [
		FooterComponent
	],
	imports: [
		CommonModule
	],
	exports: [
		FooterComponent
	]
})
export class FooterModule { }

I'm not completely sure about what is right or wrong, VS2022 creates the new project with the base for authentication in a folder called api-authorization, but I tried using Angular's forms, although ASP.NET Core handles authentication with the middlewares. As far as I've seen, you have to create the login template for the application. Is there a simpler way to use the created login html? I'd be happy to provide more details if needed

答案1

得分: 0

我告诉Jason在问题评论中,用.net6开始一个新项目解决了这个问题,但我有一种可能是我不小心删除了一些东西的感觉,所以.net的版本在这里没有任何影响。现在它能运行了。

英文:

As I've told Jason in the question comments, starting a new project with .net6 instead of .net7 solved it, but I've a feeling I might've deleted something by accident, so the version of.net makes no difference here. Now it works.

huangapple
  • 本文由 发表于 2023年6月12日 23:20:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76458079.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定