.Net Core 3.1 и React (Redux-инструментарий) Получение «Не удается получить /*» при жестком обновлении маршрутизатора react

#reactjs #webpack #react-router #asp.net-mvc-routing #asp.net-core-3.1

Вопрос:

Я хочу настроить .Сетевое базовое приложение с react (SPA). Все работает нормально. Когда я использую react rout для загрузки компонента/страницы, он работает нормально, ПОКА я не обновлю браузер. Если я обновлю обзор, я получу ошибку «Не удается ПОЛУЧИТЬ /Путь» (404). Я знаю, что этой страницы физически нет, она будет обслуживаться из JS (react), какую конфигурацию мне нужно сделать, чтобы избежать этой ошибки? Также реагируйте на горячую перезагрузку, она больше не работает.

У меня есть несколько страниц в приложении .Net Core, и я загружаю пакеты react на некоторые страницы. Пожалуйста, найдите код для обоих .Приложение Net и React ниже.

Как сохранить страницу и ее состояние при жестком обновлении и при горячей перезагрузке?

Приложение .Net

Startup.cs

 namespace AspnetCoreReact.Web
{
    public class Startup
    {
        ...

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplication();
            services.AddInfrastructure(Configuration, Environment);

            services.AddScoped<ICurrentUserService, CurrentUserService>();

            services.AddHttpContextAccessor();

            services.AddHealthChecks()
                .AddDbContextCheck<AspNetReactDbContext>();

            ConfigureCookieSettings(services);

            // Add memory cache services
            services.AddMemoryCache(); // To do: Change to distributed cache later

            services.Configure<RouteOptions>(options => options.LowercaseUrls = true);

            services.AddMvc();

            services.AddControllersWithViews();
            services.AddRazorPages();

            services.AddHttpContextAccessor();            
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();                
            }
            else
            {
                app.UseExceptionHandler("/Home/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.UseHealthChecks("/health");
            //app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();
            app.UseRouting();

            app.UseCookiePolicy();

            app.UseAuthentication();
            app.UseAuthorization();

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

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

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

                if (env.IsDevelopment())
                {
                    // Ensure that you start webpack server - npm run build
                    string webpackDevServer = "https://localhost:5010/";
                    spa.UseProxyToSpaDevelopmentServer(webpackDevServer);
                }
            });
        }
    }
}
 

Представления/Главная страница/Индекс.cshtml (представление MVC, есть другое представление, в котором я загружаю другой пакет react)

 @{
    ViewData["Title"] = "Home Page";
    ViewBag.NoContainer = true;
}


<div class="home-header">
    <h2 class="home-header-subtitle">Welcome to the</h2>
    <h1 class="home-header-title">AspnetCoreReact</h1>
    <div class="home-header-actions">
        <a class="btn btn-primary home-header-button" asp-area="" asp-controller="Editor" asp-action="Index">Try the demo</a>
    </div>
    <div id="home">
    </div>
</div>

<script src="~/spa/home.bundle.js" type="module"></script>
 

React App

webpack.dev.config.ts

 import path from "path";
import webpack from "webpack";
import * as fs from 'fs';

const modulePath = './Scripts/modules/'
const entries = {
    home: modulePath   "HomeModule.tsx",
    editor: modulePath   "EditorModule.tsx"
};

const config: webpack.Configuration = {
    mode: "development",
    output: {
        filename: "[name].bundle.js",
        publicPath: "/spa",
    },
    entry: entries,
    module: {
        rules: [
            {
                test: /.(ts|js)x?$/i,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: [
                            "@babel/preset-env",
                            "@babel/preset-react",
                            "@babel/preset-typescript",
                        ],
                    },
                },
            },
            ...            
            {
                test: /.html$/,
                use: [{
                    loader: "html-loader",
                    options: {
                        minimize: true
                    }
                }]
            }
        ],
    },
    resolve: {
        extensions: [".tsx", ".jsx", ".ts", ".js"],
    },
    plugins: [        
    ],
    devtool: "inline-source-map",
    devServer: {
        contentBase: path.join(__dirname, "build"),
        historyApiFallback: true,
        port: 5010,
        open: false,
        hot: true,
        https: {
            key: fs.readFileSync('./Scripts/generated/webpack_cert.key'),
            cert: fs.readFileSync('./Scripts/generated/webpack_cert.crt'),
        }
    }
};

export default config;
 

HomeModule.tsx (Существует несколько таких модулей, которые загружаются на разные страницы .Сетевое приложение)

 import * as React from 'react';
import * as ReactDom from 'react-dom';
import HomeComponent from '../components/HomeComponent';

const homeRoot = document.getElementById('home');

ReactDom.render(<HomeComponent msg={'Hello World!!!'} />, homeRoot);
 

Домашний компонент.tsx

 const HomeComponent = () => {
  return (
    <Router>
      <NavMenu />
      <Switch>
        <Route exact path="/" component={HomeComponent} />
        <Route exact path="/AnotherPage" component={AnotherPageComponent} />
      </Switch>
    </Router>
  )
}

export default HomeComponent
 

Ответ №1:

Добавлена резервная конечная точка в Startup.cs- > Настройка, и теперь она работает так, как ожидалось.

 endpoints.MapFallbackToController("Index", "Home");