Can';使用wwwroot作为Angular项目文件的路径,在Kestrel服务器上运行ASP.NETAPI项目时,无法获取Angular

Can';使用wwwroot作为Angular项目文件的路径,在Kestrel服务器上运行ASP.NETAPI项目时,无法获取Angular,angular,asp.net-core,kestrel-http-server,.net-5,Angular,Asp.net Core,Kestrel Http Server,.net 5,信息-我正在VS代码中成功运行并调试我的(Angular 10/ASP.Net 5)站点,连接到localhost:4200,使用>ng serve和>dotnet run,我现在想将其发布到Azure,但首先我只想在Kestrel上对其进行本地测试,通过将Angular项目构建到.NETAPI项目中的wwwroot文件夹,并从localhost:5001运行站点。我在API项目文件夹中构建(>ng build)到wwwroot,我看到所有角度文件都在wwwroot文件夹中创建,然后我执行>do

信息-我正在VS代码中成功运行并调试我的(Angular 10/ASP.Net 5)站点,连接到localhost:4200,使用>ng serve和>dotnet run,我现在想将其发布到Azure,但首先我只想在Kestrel上对其进行本地测试,通过将Angular项目构建到.NETAPI项目中的wwwroot文件夹,并从localhost:5001运行站点。我在API项目文件夹中构建(>ng build)到wwwroot,我看到所有角度文件都在wwwroot文件夹中创建,然后我执行>dotnet run

我明白了

现在收听:https://localhost:5001

然后我打开浏览器点击那个url,我在终端上看到了这些错误

信息:Microsoft.AspNetCore.Hosting.Diagnostics[1] 请求启动HTTP/1.1 GEThttps://localhost:5001/ - - 信息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] 授权失败。这些要求没有得到满足: DenyAnonymousAuthorizationRequirement:需要经过身份验证的用户。 信息:Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12] AuthenticationScheme:承载人被质询。 信息:Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] 授权失败。这些要求没有得到满足: DenyAnonymousAuthorizationRequirement:需要经过身份验证的用户。 信息:Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12] AuthenticationScheme:承载人被质询。 信息:Microsoft.AspNetCore.Hosting.Diagnostics[2] 请求已完成HTTP/1.1 GEThttps://localhost:5001/ --4010-70.3847ms

问题-这是配置问题吗?CORS/许可问题?身份验证问题?文件夹/路径问题

这里有额外的代码来帮助任何可能帮助我理解正在发生的事情的人

Startup.cs

配置服务()

Environment.ts在我的Angular项目中

导出常量环境={
制作:假,,
apiUrl:'https://localhost:5001/api/'
};我解决了我的问题。
这就是我所做的

  • 将此行添加到Startup.cs中的Configure()

    app.UseStaticFiles()

  • 除去

    .要求重新授权() 从

    endpoints.MapController().RequireAuthorization()


  • 现在它工作正常,在我的API项目中从wwwroot运行我的Ng应用程序

    在ASP.NET Core中是否有IndexController,它提供angular应用程序的index.html?您可以将[AllowAnonymous]属性添加到控制器。另一个想法是授权过滤器。不,我没有indexcontroller。加载的第一个页面不调用任何控制器。当sitelaods已经设置为匿名时,首先被调用的主页是哪个代码提供index.html?您有:
    endpoints.MapFallbackToController(“Index”,“Fallback”)这是什么?你读过吗?你好,你缺少根路径,请看下面我的答案。
    
    public void ConfigureServices(IServiceCollection services)
        {
            services.AddAutoMapper(typeof(MappingEvents));
            services.AddAutoMapper(typeof(MappingMembers));
            services.AddAutoMapper(typeof(MappingUsers));
            services.AddAutoMapper(typeof(MappingYogabands));
            services.AddAutoMapper(typeof(MappingReviews));
            // services.AddControllers();
            services.AddControllers()
                .AddNewtonsoftJson(opt => 
                {
                    opt.SerializerSettings.ReferenceLoopHandling =
                         Newtonsoft.Json.ReferenceLoopHandling.Ignore;
                });
    
    
            services.AddDbContext<DataContext>(x =>
                x.UseSqlServer(_config.GetConnectionString("SqlServerConnection"), y => y.UseNetTopologySuite()));
    
            services.AddTransient<IEmailSender, EmailSender>();
            services.Configure<AuthMessageSenderOptions>(_config.GetSection("SendGrid"));
            services.Configure<ConfirmationOptions>(_config.GetSection("Confirmation"));
    
            services.Configure<CloudinarySettings>(_config.GetSection("CloudinarySettings"));
            
            services.AddApplicationServices();
            services.AddIdentityServices(_config);
            services.AddSwaggerDocumentation();
    
    
            // telling out client app, that if it's running on an unsecure port, we won't return a header, 
            // that will allow our browser to display that information
            // * only allowed to access info from localhost:4200, all others will be denied?
            services.AddCors(opt => 
            {
                opt.AddPolicy("CorsPolicy", policy => 
                {
                    policy.AllowAnyHeader().AllowAnyMethod().WithOrigins("https://localhost:4200");
                });
            });
        }
    
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseMiddleware<ExceptionMiddleware>();
    
            // when coming into the server and we don't have an endpoint that matches the request, then we hit this below
            // it will then re direct to our error controller, pass in the status code and return an object result
            app.UseStatusCodePagesWithReExecute("/errors/{0}"); // after creating ErrorController
    
            app.UseHttpsRedirection();
    
            app.UseRouting();
    
            app.UseCors("CorsPolicy");
    
            app.UseAuthentication();
            app.UseAuthorization();
    
            app.UseSwaggerDocumention();
    
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers().RequireAuthorization();
                // endpoints.MapControllers();
                endpoints.MapFallbackToController("Index", "Fallback");
            });
        }
    
    public static IServiceCollection AddIdentityServices(this IServiceCollection services, IConfiguration config)
        {
            services.Configure<IdentityOptions>(options =>
            {
                options.User.RequireUniqueEmail = true;
                options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@";
            });
    
            var builder = services.AddIdentityCore<User>(opt =>
            {
                opt.Password.RequireDigit = false;
                opt.Password.RequiredLength = 2;
                opt.Password.RequireNonAlphanumeric = false;
                opt.Password.RequireUppercase = false;
                // *******************************************************
                // for email confirmation
                opt.SignIn.RequireConfirmedEmail = true;
                // *******************************************************
            });
    
            builder = new IdentityBuilder(builder.UserType, typeof(Role), builder.Services);
            // AddDefaultTokenProviders() allows the ability to create a token to send to user when they forgot password
            builder.AddEntityFrameworkStores<DataContext>().AddDefaultTokenProviders();
            
            // for roles
            builder.AddRoleValidator<RoleValidator<Role>>();
            builder.AddRoleManager<RoleManager<Role>>();
    
            builder.AddSignInManager<SignInManager<User>>();
    
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options => 
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["Token:Key"])),
                        ValidIssuer = config["Token:Issuer"],
                        ValidateIssuer = true,
                        ValidateAudience = false
                    };
                });
    
            services.AddAuthorization(options =>
            {
                options.AddPolicy("RequireAdminRole", policy => policy.RequireRole("Admin"));
                options.AddPolicy("ModeratePhotoRole", policy => policy.RequireRole("Admin", "Moderator"));
                options.AddPolicy("VipOnly", policy => policy.RequireRole("VIP"));
            });
    
            return services;
        }
    
    "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "allowedCommonJsDependencies": ["angular2-wizard", "hammerjs"],
            "outputPath": "../API/wwwroot",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "aot": true,
            "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,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            }
          }
        }