在同一应用服务上响应 asp.net SPA 调用 API

React asp.net SPA calling API on same app service

我有一个包含两个项目的解决方案:

我已经使用虚拟目录将这两个项目部署到一个 Azure 应用程序服务。 Virtual Directory Setup

当 Foo 应用程序调用 https://azureFooapp.com/api/getData 时,所有返回的都是来自 Foo 项目的 index.html 文件。而不是实际调用位于 Bar API 项目中的端点。

如果我从 App Service 中删除 Foo project project,我就能成功到达端点 https://azureFooapp.com/api/getData

富Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
    
    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();

        // In production, the React files will be served from this directory
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/build";
        });

        services.AddControllers()
        .AddNewtonsoftJson();

        services.AddMvc().AddNewtonsoftJson(o =>
        {
            o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseSpaStaticFiles();

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller}/{action=Index}/{id?}");
        });

        app.UseSpa(spa =>
        {
            spa.Options.SourcePath = "ClientApp";

            if (env.IsDevelopment())
            {
                spa.UseReactDevelopmentServer(npmScript: "start");
            }
        });
    }
}

小节Startup.cs

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));

    services.AddControllers();
    services.AddControllersWithViews();

    
    services.AddControllers()
    .AddNewtonsoftJson();

    services.AddMvc().AddNewtonsoftJson(o =>
    {
        o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    });

    services.AddCors(options => 
    { 
        options.AddPolicy("AllowSpecificOrigin", builder =>
        { 
            builder.WithOrigins("https://localhost").AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod(); 
        }); 
    });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseCors("AllowSpecificOrigin");

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

任何人都可以帮助完成这项工作吗?如果需要更多信息,请告诉我

建议你把api工程放在wwwroot下,react工程放在虚拟目录下

喜欢:

Virtual path     Physical Path                     Type   
/                site\wwwroot                    Application
/pages           site\wwwroot\react_folder       Application

建议

  1. 为什么不建议把nodejs项目,比如react,angular,vue项目放到主应用中?

    经过大量测试,发现当主应用放入这三项时,虚拟应用不会生效,放入虚拟应用可以正常工作。

  2. (不推荐)react项目编译后,如果释放dist文件夹内容,iis中支持虚拟应用的路由访问,不推荐这样做

我现在已经通过修改 Foo Startup.cs 中的代码解决了这个问题

 app.MapWhen(x => !x.Request.Path.Value.ToLower().StartsWith("/api"), builder =>
        {
            builder.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });
        });

之后我重新启动了应用服务