从 .net 8 中 root 以外的路径运行 SPA

问题描述 投票:0回答:1

我正在尝试设置一个实验性的 C# 8 服务器,该服务器可以运行 Web API、Razor 页面,还可以运行特定路径(例如“/spa1”)之外的各种 React 应用程序,但无法让 SPA 在路径之外提供服务。根据我在下面列出的一些相关堆栈溢出问题(以及其他一些问题)中读到的内容,这应该可行。

*注:我的客户端目录是

{SolutionFolder}\projects\cs.web.client
,Web 服务器是
{SolutionFolder}\projects\CS.Web.Server

public static class SpaApplicationBuilderExtensions
{
    public static void EnableReactApp(this WebApplication app, string spaPath, string codePath, int serverPort, bool isDev = false)
    {
        ArgumentNullException.ThrowIfNull(app);
        ArgumentException.ThrowIfNullOrEmpty(spaPath);
        ArgumentException.ThrowIfNullOrEmpty(codePath); 

        app.Map(new PathString(spaPath), client =>
        {
            client.UsePathBase(new PathString(spaPath));
            //client.UseSpaStaticFiles();
            client.UseSpa(spa =>
            {
                var path = Path.Combine((Directory.GetParent(Directory.GetCurrentDirectory()))?.FullName ?? string.Empty, codePath);
                spa.Options.SourcePath = path;
                spa.Options.DefaultPageStaticFileOptions = new StaticFileOptions
                {
                    FileProvider = new PhysicalFileProvider(path)
                    {
                        UseActivePolling = true,
                    },
                    RedirectToAppendTrailingSlash = true,
                };

                if (isDev)
                {
                    spa.Options.DevServerPort = serverPort;
                    spa.UseReactDevelopmentServer("dev");
                }
            });
        });
    }
}

程序.CS

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
IMvcBuilder? views = builder.Services.AddControllersWithViews();
IMvcBuilder? pages = builder.Services.AddRazorPages();

#if (DEBUG)
views.AddRazorRuntimeCompilation();
pages.AddRazorRuntimeCompilation();
#endif

var app = builder.Build();

app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseRouting();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.MapControllers();

if (app.Environment.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.EnableReactApp("/spa1", "cs.web.client", 707, app.Environment.IsDevelopment());

app.Run();

而且,事实上,当我运行这个时,我可以看到 vite 正在

https://localhost:707
为 React 应用程序提供服务,这是它应该做的。但是,当我转到
https://localhost:7788/spa1
时,我收到此错误消息:
TimeoutException: The create-react-app server did not start listening for requests within the timeout period of 120 seconds. Check the log output for error information.

我的 Razor 页面和其他 API 端点工作正常。

我一直在看的相关问题:

我还尝试研究模板正在做什么,以确保我做得正确,但是想要将

"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
添加到启动配置文件中的环境变量中,这需要所有设置都位于 csproj 文件中,并且这似乎没有办法让你将其设置为特定路径,我也无法运行多个 SPA。

这是我的

vite.config.ts

const baseFolder = env.APPDATA !== undefined && env.APPDATA !== ''
    ? `${env.APPDATA}/ASP.NET/https`
    : `${env.HOME}/.aspnet/https`;

const certificateName = "cs.web.client";
const certFilePath = path.join(baseFolder, `${certificateName}.pem`);
const keyFilePath = path.join(baseFolder, `${certificateName}.key`);

if (!fs.existsSync(certFilePath) || !fs.existsSync(keyFilePath)) {
    if (0 !== child_process.spawnSync('dotnet', [
        'dev-certs',
        'https',
        '--export-path',
        certFilePath,
        '--format',
        'Pem',
        '--no-password',
    ], { stdio: 'inherit', }).status) {
        throw new Error("Could not create certificate.");
    }
}

const target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :
    env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:7788';

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [plugin()],
    resolve: {
        alias: {
            '@': fileURLToPath(new URL('./src', import.meta.url))
        }
    },
    server: {
        proxy: {
            '^/weatherforecast': {
                target,
                secure: false
            },
        },
        port: 707,
        https: {
            key: fs.readFileSync(keyFilePath),
            cert: fs.readFileSync(certFilePath),
        }
    }
})

谢谢!

c# asp.net-core single-page-application .net-8.0 asp-net-core-spa-services
1个回答
0
投票

尝试添加回退端点,这会告诉主机(在本例中为 .net 应用程序)对于 razor 页面中未定义的路径回退到

/reactapp

public static class SpaApplicationBuilderExtensions
{
    public static void EnableReactApp(this WebApplication app, string spaPath)
    {
        ArgumentNullException.ThrowIfNull(app);
        ArgumentException.ThrowIfNullOrEmpty(spaPath);
        ArgumentException.ThrowIfNullOrEmpty(codePath); 

        app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
                endpoints.MapFallbackToPage(spaPath);
            });
    }
}

然后创建一个传递到反应应用程序的页面,其名称类似于您的路径

spa1.cshtml

@page

@{
    Layout = null;
    ViewData["Title"] = "React App";
}

@* Entry point for our react app *@
@* The id is the same as the one that react references in index.tsx *@
<div id="react-app"></div>

<environment names="Development">
    <script src="~/vite.config.ts"></script>
</environment>
<environment names="Staging,Production">
    <script src="~/vite.config.ts" asp-append-version="true"></script>
</environment>

如果运行,您的 React 应用程序将在放置

<div id="react-app"></div>
的位置进行渲染。

© www.soinside.com 2019 - 2024. All rights reserved.