После переноса моего приложения на ASP.NET Core 3.0 ранее действующий URL-адрес индекса возвращает 404

Приложение запустилось в ASP.NET Core 2.0 (я думаю), затем перешло на 2.1, затем на 2.2, теперь я пытаюсь и не могу перенести его на 3.0 ...

Я прочитал и попытался применить инструкции в официальные документы по миграции, согласно которым я должен был (среди прочего) заменить services.AddMvc() на services.AddRazorPages() и app.UseMvc() на app.UseEndpoints(endpoints => {endpoints.MapRazorPages();}), если я использовал Razor Pages. Поскольку, насколько мне известно, я всегда использовал Razor Pages и никогда не использовал полноценный MVC, именно это я и сделал.

Теперь ранее работающие URL-адреса возвращают HTTP 404 вместо любого контента ...

Например, маршрут / или /Index делает это, даже если в каталоге проекта есть файл Pages/Index.cshtml, а также файл Pages/Index.cshtml.cs. (Хотя, как ни странно: может быть, не работает только URL-адрес индекса - я просто попытался указать в браузере /Error, и это сработало!)

Pages/Index.cshtml.cs содержание (без изменений по сравнению с рабочей версией):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Mon.Battle;

namespace mon.Pages
{
    public class IndexModel : PageModel
    {
        public IndexModel(IBattleManager battleManager)
        {
            // I hope I don't have to lock this dict here, I'm only reading
            configurationSerialized = battleManager.configurationSerialized;
        }

        public ConfigurationSerializedFormat configurationSerialized;

        public void OnGet()
        {

        }
    }
}

Pages/Index.cshtml также содержит некоторый контент, но он слишком длинный и слишком беспорядочный, чтобы размещать его здесь целиком ... Но он определенно должен что-то возвращать, и он что-то возвращал перед переходом на 3.0.

Однако директивы страниц в начале Index.cshtml достаточно короткие:

@* TODO: The site becomes ugly :( Should I start using Bootstrap, instead of trying to handcraft CSS? *@
@* Hey... I actually start to like how the site looks :) *@

@page

@using System.Text.Encodings.Web
@using Microsoft.Extensions.Configuration
@inject JavaScriptEncoder jsencoder
@inject IConfiguration conf
@using static System.Text.Json.JsonSerializer
@model IndexModel
@{
    Layout = null;
}

К сожалению, они должны были немного измениться по сравнению с версией до миграции: а именно, поскольку 3.0 удалил Newtonsoft.JSON, мне пришлось заменить его на System.Text.Json.

Мой текущий Startup.cs (я думал, что применил инструкции из вышеупомянутых документов в точности):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.EntityFrameworkCore;
using mon.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Mon.Chat;
using Mon.MatchMaker;
using Mon.Battle;
using Mon.Player;

namespace mon
{
    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.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.Configure<IdentityOptions>(options =>
            {
                options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            });

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            services.AddDefaultIdentity<ApplicationUser>().AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddRazorPages();

            services.AddSignalR();

            services.AddSingleton<IBattleManager, BattleManager>();
        }

        // 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.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();

            app.UseAuthentication();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<ChatHub>("/chathub");
                endpoints.MapHub<MatchMakerHub>("/mmrhub");
                endpoints.MapHub<BattleHub>("/battlehub");
                endpoints.MapRazorPages();
            });
        }
    }
}

Предыдущий Startup.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using mon.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Mon.Chat;
using Mon.MatchMaker;
using Mon.Battle;
using Newtonsoft.Json.Serialization;
using Mon.Player;

namespace mon
{
    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.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.Configure<IdentityOptions>(options =>
            {
                options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            });

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));
            services.AddDefaultIdentity<ApplicationUser>().AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services
                .AddSignalR()
                .AddJsonProtocol(options =>
                {
                    options.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver();
                });

            services.AddSingleton<IBattleManager, BattleManager>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseAuthentication();

            app.UseSignalR(routes =>
            {
                routes.MapHub<ChatHub>("/chathub");
                routes.MapHub<MatchMakerHub>("/mmrhub");
                routes.MapHub<BattleHub>("/battlehub");
            });

            app.UseMvc();
        }
    }
}

Что я делаю неправильно? Что я пропустил? Почему /Index возвращает HTTP 404?

Если вы попросите дополнительную информацию, я предоставлю.


person Community    schedule 11.11.2019    source источник
comment
Index.chstml может быть слишком длинным для публикации, но можно ли разместить директивы страницы вверху без фактического содержания?   -  person Jonathon Chase    schedule 11.11.2019
comment
@JonathonChase Done.   -  person    schedule 11.11.2019
comment
Можете ли вы убедиться, что для BuildAction в index.cshtml установлено значение Content? (Щелкните правой кнопкой мыши, выберите свойства)   -  person Jonathon Chase    schedule 11.11.2019
comment
@JonathonChase был установлен на None. Я установил его на Content, и, наконец, кажется, что он работает! Не знаю, что случилось, но спасибо!   -  person    schedule 11.11.2019
comment
С ядром вы можете проверить файл .csproj и безопасно удалить директивы содержимого на ваших страницах razor - они включены в сборку по умолчанию.   -  person Jonathon Chase    schedule 11.11.2019


Ответы (1)


Однажды у меня возникла проблема с моим файлом .csproj. Убедитесь, что ваших файлов нет в списке, например:

<ItemGroup>
   <Content Remove="Views\Extractor\Insert.cshtml" />
   <Content Remove="Views\_ViewImports.cshtml" />
</ItemGroup>

Это может произойти, когда мы копируем и вставляем файл / меняем действие сборки и т. Д.

person Nirmal Subedi    schedule 11.11.2019
comment
Ага, у меня было <ItemGroup><Content Remove="Pages\Index.cshtml" /></ItemGroup>. Не уверен, что случилось. Но удаление этого, похоже, решило проблему. Спасибо! - person ; 11.11.2019