Angular 7 with .net core 2.1 - 针对特定页面启动
Angular 7 with .net core 2.1 - Launching for specific page
我有一个 .NET Core 2.1 网站,其中 Angular 7 位于 /ClientApp 中。
我正在使用 Microsoft.AspNetCore.SpaServices.Extensions
如果我转到某个页面,例如localhost:5001/pagedoesnotexist/index 然后由于某种原因 Angular 应用程序启动。
问题 - 如何更改配置,以便 ASP.NET Core 在我转到不存在的页面时不会尝试重定向到 Angular 应用程序?
我希望它在不正确的 Web 请求时简单地 return 一个标准的 404。
我想要一个特定的页面,例如/admin/dashboard 仅提供 Angular 应用
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
...
}
虽然这是我的第一个 Angular 应用程序,但到目前为止它似乎运行良好,问题出在开发环境中。
谢谢。
更新 1
进一步澄清:
通过:我要localhost:5001/=404
通过:我希望 localhost:5001/angtastic/ 为应用程序提供服务
失败:我从 zone.js (socksjs-node/info) 得到重复的信息?t=[随机数]
(它在没有以下针对子文件夹的代码的情况下工作,所以也许我做错了什么)。
我的猜测是套接字或与 webpack 有关的东西(在 angular cli 的引擎盖下)在处理此子文件夹中的应用程序时遇到问题。
我有一个带有问题的部分解决方案:
app.Map(new PathString("/angtastic"), angtastic =>
{
angtastic.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start --app=angtastic --base-href=/angtastic/ --serve-path=/angtastic/ ");
}
});
});
另外,将 index.html 的 BaseURL 更改为 .
这是我的 Angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"angtastic": {
"root": "src",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"styleext": "scss"
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/angtastic",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "angtastic:build"
},
"configurations": {
"production": {
"browserTarget": "angtastic:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "angtastic:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"clientapp/src/styles.scss"
],
"scripts": [],
"assets": [
"clientapp/src/favicon.ico",
"clientapp/src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"angtastic-e2e": {
"root": "e2e/",
"projectType": "application",
"prefix": "",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "angtastic:serve"
},
"configurations": {
"production": {
"devServerTarget": "angtastic:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "angtastic"
}
如何在 .net 核心应用程序上实现 subfolder/subdirectory 特定的 angular 应用程序,其中 angular 7 应用程序包含在 .net 核心 2.1 应用程序的 ClientApp 目录中(运行 使用 "dotnet watch run" 命令),其中 "angtastic" 是您的项目和子文件夹的名称:
- 添加上面的 app.Map(newPathString("/angtastic"), angtastic => ... 然后使用 spa.UseAngularCliServer(npmScript: "start") 或 UseProxyToSpaDevelopmentServer 作为适当的你的项目。
- 在启动时不要在行 spa.UseAngularCliServer(npmScript: "start");
中添加任何参数
我的 ClientApp 文件夹中的 - Package.json 只是 "start": "ng serve" 因为参数已放入 angular.json 配置文件中 Angular- CLI
我是如何解决上面的 info?t=XXX 问题的,在 angular.json 的 "serve" 部分添加以下内容:
"browserTarget": "angtastic:build",
"baseHref": "/angtastic/",
"publicHost": "",
"servePath" : "/"
如果您更喜欢 package.json 中的启动命令,您可以将这些作为选项传递,但我更喜欢将内容保留在 angular.json 中,但请记住 servePath 将是 --serve-path= "/"
- 检查你的 angular.json 有 "root" : "src" 和 "sourceRoot": "src"
- 运行 使用 "dotnet watch run" 从根目录(在 ClientApp 之上)的项目并打开浏览器到 localhost:5001/angtastic
的安全版本
- 打开开发工具确认您已成功。如果您没有看到来自 zonejs 的 404 流,那么一切看起来都不错。我只看到一个 info?t=xxxx(200 代码)和一个 xhr_streaming?t=XXXX(也是 200)。
publicHost 是这个答案的真正本质,因为它指示(我认为)webpack 实时重新加载到正确的端口。此答案可能适用于其他平台,但请记住,您可能需要将端口替换为您的应用正在使用的端口,例如3000/3001.
希望这对某人有所帮助!这里的第一个应用程序,到目前为止它是一场斗争。
段.
有同样的问题,
"publicHost":"https://localhost:5001/management/sockjs-node"
已修复。
"serve" 配置:
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "ManagementClient:build",
"publicHost":"https://localhost:5001/management/sockjs-node"
},
"configurations": {
"production": {
"browserTarget": "ManagementClient:build:production",
"baseHref" : "/management/",
"servePath": "/management/"
}
}
},
我正在使用 .Net Core 2.2 并使用 Docker 发布我的应用程序,所以在我的 Configure
我在开发中使用 UseAngularCliServer
并且只在产品上提供静态文件。
注意路径,很乱
在 package.json
我添加了一个新脚本:
"scripts": {
...
"start": "ng serve",
"start-dotnet": "ng serve --baseHref=/<<SUBFOLDER>>/ --servePath=/ --publicHost=0.0.0.0/<<SUBFOLDER>>/sockjs-node/",
...
},
在 Startup.cs
:
public void ConfigureServices(IServiceCollection services) {
...
services.AddSpaStaticFiles(configuration => { configuration.RootPath = "wwwroot"; });
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
...
app.Map(
"/<<SUBFOLDER>>",
builder =>
{
builder.UseSpa(spa =>
{
if (env.IsDevelopment())
{
spa.Options.SourcePath = "<<PATH-TO-ANGULAR>>";
spa.UseAngularCliServer(npmScript: "start-dotnet");
}
else
{
spa.Options.SourcePath = "wwwroot/<<SUBFOLDER>>";
spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/<<SUBFOLDER>>"))
};
}
});
}
);
...
}
在 Dockerfile
:
# Build Angular
FROM node:10-alpine AS build-angular
WORKDIR /usr/src/app
COPY ./<<PATH-TO-ANGULAR>>/package.json ./
COPY ./<<PATH-TO-ANGULAR>>/package-lock.json ./
RUN npm install
COPY ./<<PATH-TO-ANGULAR>>/ .
RUN npm run build -- --prod --baseHref /<<SUBFOLDER>>/
# Build API
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-alpine AS build-api
WORKDIR /app
COPY ./<<PATH-TO-DOTNET>>/ ./
RUN dotnet publish -c Release -o out
# Docker
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-alpine
WORKDIR /app
COPY --from=build-angular /usr/src/app/dist ./wwwroot/<<SUBFOLDER>>
COPY --from=build-api /<<PATH-TO-DOTNET-OUT>>/out .
ENTRYPOINT ["dotnet", "<<DOTNET-DLL>>"]
EXPOSE 80
我有一个 .NET Core 2.1 网站,其中 Angular 7 位于 /ClientApp 中。
我正在使用 Microsoft.AspNetCore.SpaServices.Extensions
如果我转到某个页面,例如localhost:5001/pagedoesnotexist/index 然后由于某种原因 Angular 应用程序启动。
问题 - 如何更改配置,以便 ASP.NET Core 在我转到不存在的页面时不会尝试重定向到 Angular 应用程序?
我希望它在不正确的 Web 请求时简单地 return 一个标准的 404。
我想要一个特定的页面,例如/admin/dashboard 仅提供 Angular 应用
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
...
}
虽然这是我的第一个 Angular 应用程序,但到目前为止它似乎运行良好,问题出在开发环境中。
谢谢。
更新 1
进一步澄清:
通过:我要localhost:5001/=404
通过:我希望 localhost:5001/angtastic/ 为应用程序提供服务
失败:我从 zone.js (socksjs-node/info) 得到重复的信息?t=[随机数] (它在没有以下针对子文件夹的代码的情况下工作,所以也许我做错了什么)。 我的猜测是套接字或与 webpack 有关的东西(在 angular cli 的引擎盖下)在处理此子文件夹中的应用程序时遇到问题。
我有一个带有问题的部分解决方案:
app.Map(new PathString("/angtastic"), angtastic =>
{
angtastic.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start --app=angtastic --base-href=/angtastic/ --serve-path=/angtastic/ ");
}
});
});
另外,将 index.html 的 BaseURL 更改为 .
这是我的 Angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"angtastic": {
"root": "src",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"styleext": "scss"
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/angtastic",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "angtastic:build"
},
"configurations": {
"production": {
"browserTarget": "angtastic:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "angtastic:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"clientapp/src/styles.scss"
],
"scripts": [],
"assets": [
"clientapp/src/favicon.ico",
"clientapp/src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"angtastic-e2e": {
"root": "e2e/",
"projectType": "application",
"prefix": "",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "angtastic:serve"
},
"configurations": {
"production": {
"devServerTarget": "angtastic:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "angtastic"
}
如何在 .net 核心应用程序上实现 subfolder/subdirectory 特定的 angular 应用程序,其中 angular 7 应用程序包含在 .net 核心 2.1 应用程序的 ClientApp 目录中(运行 使用 "dotnet watch run" 命令),其中 "angtastic" 是您的项目和子文件夹的名称:
- 添加上面的 app.Map(newPathString("/angtastic"), angtastic => ... 然后使用 spa.UseAngularCliServer(npmScript: "start") 或 UseProxyToSpaDevelopmentServer 作为适当的你的项目。
- 在启动时不要在行 spa.UseAngularCliServer(npmScript: "start"); 中添加任何参数 我的 ClientApp 文件夹中的
- Package.json 只是 "start": "ng serve" 因为参数已放入 angular.json 配置文件中 Angular- CLI
我是如何解决上面的 info?t=XXX 问题的,在 angular.json 的 "serve" 部分添加以下内容:
"browserTarget": "angtastic:build",
"baseHref": "/angtastic/",
"publicHost": "",
"servePath" : "/"
如果您更喜欢 package.json 中的启动命令,您可以将这些作为选项传递,但我更喜欢将内容保留在 angular.json 中,但请记住 servePath 将是 --serve-path= "/"
- 检查你的 angular.json 有 "root" : "src" 和 "sourceRoot": "src"
- 运行 使用 "dotnet watch run" 从根目录(在 ClientApp 之上)的项目并打开浏览器到 localhost:5001/angtastic 的安全版本
- 打开开发工具确认您已成功。如果您没有看到来自 zonejs 的 404 流,那么一切看起来都不错。我只看到一个 info?t=xxxx(200 代码)和一个 xhr_streaming?t=XXXX(也是 200)。
publicHost 是这个答案的真正本质,因为它指示(我认为)webpack 实时重新加载到正确的端口。此答案可能适用于其他平台,但请记住,您可能需要将端口替换为您的应用正在使用的端口,例如3000/3001.
希望这对某人有所帮助!这里的第一个应用程序,到目前为止它是一场斗争。
段.
有同样的问题,
"publicHost":"https://localhost:5001/management/sockjs-node"
已修复。
"serve" 配置:
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "ManagementClient:build",
"publicHost":"https://localhost:5001/management/sockjs-node"
},
"configurations": {
"production": {
"browserTarget": "ManagementClient:build:production",
"baseHref" : "/management/",
"servePath": "/management/"
}
}
},
我正在使用 .Net Core 2.2 并使用 Docker 发布我的应用程序,所以在我的 Configure
我在开发中使用 UseAngularCliServer
并且只在产品上提供静态文件。
注意路径,很乱
在 package.json
我添加了一个新脚本:
"scripts": {
...
"start": "ng serve",
"start-dotnet": "ng serve --baseHref=/<<SUBFOLDER>>/ --servePath=/ --publicHost=0.0.0.0/<<SUBFOLDER>>/sockjs-node/",
...
},
在 Startup.cs
:
public void ConfigureServices(IServiceCollection services) {
...
services.AddSpaStaticFiles(configuration => { configuration.RootPath = "wwwroot"; });
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
...
app.Map(
"/<<SUBFOLDER>>",
builder =>
{
builder.UseSpa(spa =>
{
if (env.IsDevelopment())
{
spa.Options.SourcePath = "<<PATH-TO-ANGULAR>>";
spa.UseAngularCliServer(npmScript: "start-dotnet");
}
else
{
spa.Options.SourcePath = "wwwroot/<<SUBFOLDER>>";
spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/<<SUBFOLDER>>"))
};
}
});
}
);
...
}
在 Dockerfile
:
# Build Angular
FROM node:10-alpine AS build-angular
WORKDIR /usr/src/app
COPY ./<<PATH-TO-ANGULAR>>/package.json ./
COPY ./<<PATH-TO-ANGULAR>>/package-lock.json ./
RUN npm install
COPY ./<<PATH-TO-ANGULAR>>/ .
RUN npm run build -- --prod --baseHref /<<SUBFOLDER>>/
# Build API
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-alpine AS build-api
WORKDIR /app
COPY ./<<PATH-TO-DOTNET>>/ ./
RUN dotnet publish -c Release -o out
# Docker
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-alpine
WORKDIR /app
COPY --from=build-angular /usr/src/app/dist ./wwwroot/<<SUBFOLDER>>
COPY --from=build-api /<<PATH-TO-DOTNET-OUT>>/out .
ENTRYPOINT ["dotnet", "<<DOTNET-DLL>>"]
EXPOSE 80