简体   繁体   English

.NET Core,Angular2,NancyFX-404在浏览器中更改URL

[英].NET Core, Angular2, NancyFX - 404 changing URL in browser

When serving the application with .NET Core static files I'm unable to change the URL in the browser. 当使用.NET Core静态文件为应用程序提供服务时,我无法在浏览器中更改URL。 When doing so I'm given the 这样做时,我得到了

404 - Not Found 404-找不到

Nancy error page. 南希错误页面。

The only URL that's working is the base URL, localhost:5000. 唯一有效的URL是基本URL localhost:5000。 Changing the URL to localhost:5000/reservations gives me 404. Pressing F5 when not on the base URL will also result in a 404. 将URL更改为localhost:5000 / reservations给我404。不在基本URL上时按F5也将产生404。

If I use the browsersync url, localhost:4200, everything works and I can change the URL and press F5 without 404. This is what I'm doing when developing but not when it's deployed on the server using IIS. 如果使用浏览器同步URL localhost:4200,则一切正常,并且可以更改URL并按F5而不使用404。这是我在开发时正在执行的操作,而不是在使用IIS将其部署在服务器上时执行的操作。

Running the application in IIS Express 在IIS Express中运行应用程序

  1. ng build (files are copied over to wwwroot along with index.html) ng构建(文件和index.html一起复制到wwwroot)

  2. start IIS Express 启动IIS Express

Startup.cs 启动文件

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();

        env.ConfigureNLog("nlog.config");
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(IISDefaults.AuthenticationScheme);

        services.AddMvc(config =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            config.Filters.Add(new AuthorizeFilter(policy));
        });

        services.AddMvc();

        services.InjectServices();

        services.AddOptions();

        services.Configure<Endpoints>(Configuration.GetSection("Endpoints"));

        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

        services.AddSingleton<IConfiguration>(Configuration);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        app.Use(async (context, next) =>
        {
            await next();
            if (!context.Request.Path.Value.StartsWith("/api/"))
            {
                context.Request.Path = "/index.html";
                await next();
            }
        });

        app.UseDefaultFiles();

        app.UseStaticFiles();

        loggerFactory.AddNLog();

        app.AddNLogWeb();

        app.UseOwin(x => x.UseNancy(new NancyOptions
        {
            Bootstrapper = new Bootstrapper(app)
        }));
    }
}

Bootstrapper.cs Bootstrapper.cs

public class Bootstrapper : DefaultNancyBootstrapper
{
    readonly IApplicationBuilder _app;

    public Bootstrapper(IApplicationBuilder app)
    {
        _app = app;
    }

    protected override void ConfigureApplicationContainer(TinyIoCContainer container)
    {
        base.ConfigureApplicationContainer(container);

        container.Register<IOptions<Endpoints>>(_app.ApplicationServices.GetService<IOptions<Endpoints>>());

        container.Register<IReservationService>(_app.ApplicationServices.GetService<IReservationService>());
    }
}

wwwroot wwwroot

在此处输入图片说明

index.html index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>XXX</title>
    <base href="/">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="icon" type="image/x-icon" href="XXX">
    <link href="styles.61cc257ef8131303860b.bundle.css" rel="stylesheet" />
</head>
<body>
    <app-root></app-root>
    <script type="text/javascript" src="inline.f68c652d205feae6e02a.bundle.js"></script>
    <script type="text/javascript" src="polyfills.756a44edc7e0a68ce65c.bundle.js"></script>
    <script type="text/javascript" src="vendor.940a3ce39a746f717f7b.bundle.js"></script>
    <script type="text/javascript" src="main.d5f9dd82a3600822cae2.bundle.js"></script>
</body>
</html>

I understand that there is some problem with the handling of static content from the server but I can't seem to figure it out. 我了解服务器的静态内容处理存在一些问题,但似乎无法解决。

How can I navigate around using the browser URL when hosting the Angular application in .NET Core? 在.NET Core中托管Angular应用程序时,如何使用浏览器URL浏览?

Update 1: 更新1:

After adding: 添加后:

PerformPassThrough = (context => context.Response.StatusCode == HttpStatusCode.NotFound)

the 404 error message goes away but page is now blank without any error message except the 404 in the console.. 404错误消息消失,但是页面现在为空白,除了控制台中的404以外,没有任何错误消息。

在此处输入图片说明

IMO the middleware you wrote should be after the app.UseDefaultFiles(); IMO您编写的中间件应位于app.UseDefaultFiles();之后; and app.UseStaticFiles(); 和app.UseStaticFiles(); And you are only handling API requests. 而且,您仅在处理API请求。 Try to rewrite it a little bit to also handle 404 errors and to not handle requests with extensions: 尝试稍微重写一下它,以同时处理404错误和不处理带有扩展名的请求:

app.Use(async (context, next) =>
{
    await next();

    if (context.Response.StatusCode == 404
        && !Path.HasExtension(context.Request.Path.Value)
        && !context.Request.Path.Value.StartsWith("/api/"))
    {
        context.Request.Path = "/index.html";
        await next();
    }
});

You need to remove the first await next(); 您需要删除第一次await next(); . That's sending the request to /reservations down the pipeline, before rewriting the URL to index.html . 那是将URL重写为index.html 之前,将请求发送到/reservations管道。

When it hits Nancy, it'll see if it can handle /reservations , which it can't, and render a 404 page. 当它到达Nancy时,它会查看它是否可以处理/reservations (它不能处理)并呈现404页面。

  1. Modified Startup.cs 修改后的Startup.cs
  2. Added module that returns index.html for all requests. 添加了针对所有请求返回index.html的模块。
  3. Configured root path in bootstrapper.cs. 在bootstrapper.cs中配置的根路径。

Startup.cs 启动文件

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    //For serving index.html on baseurl - this can we done in AppNancyModule aswell: Get("/", _ => View["index"]);
    app.UseDefaultFiles();

    app.UseStaticFiles();

    loggerFactory.AddNLog();

    app.AddNLogWeb();

    app.UseOwin(x => x.UseNancy(new NancyOptions
    {
        Bootstrapper = new Bootstrapper(app, env)
    }));
}

AppNancyModule AppNancyModule

public class AppNancyModule : NancyModule
{
    public AppNancyModule()
    {
        //Get("/", _ => View["index"]);

        Get(@"^(.*)$", _ => View["index"]);
    }
}

Bootstrapper.cs Bootstrapper.cs

public class AppRootPathProvider : IRootPathProvider
{
    private readonly IHostingEnvironment _environment;

    public AppRootPathProvider(IHostingEnvironment environment)
    {
        _environment = environment;
    }
    public string GetRootPath()
    {
        return _environment.WebRootPath;
    }
}

public class Bootstrapper : DefaultNancyBootstrapper
{
    readonly IApplicationBuilder _app;

    protected override IRootPathProvider RootPathProvider { get; }

    public Bootstrapper(IApplicationBuilder app, IHostingEnvironment environment)
    {
        RootPathProvider = new AppRootPathProvider(environment);
        _app = app;
    }

    protected override void ConfigureApplicationContainer(TinyIoCContainer container)
    {
        base.ConfigureApplicationContainer(container);

        container.Register<IOptions<Endpoints>>(_app.ApplicationServices.GetService<IOptions<Endpoints>>());

        container.Register<IReservationService>(_app.ApplicationServices.GetService<IReservationService>());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM