1
votes

I have an ASP.NET Core 2.0 app and I have Angular 5 app. Those are developed separately (1st in VS2017, 2nd in VS Code). So I set up CD/CI in VSTS and Angular app gets injected into /angularapp/ folder of ASP.NET Core app during the build.

In order to make angular app work when user opens http://domain/angularapp I set up URL rewrite rule in IIS (so when it hits /angularapp it gets rewritten to /angularapp/index.html).

But what about deeper links in Angular app? If I try to open /angularapp/feature I get the 404 error from ASP.NET Core 2.0. Can I workaround this?

4

4 Answers

3
votes

Janne-Harju is right. The solution is here - https://code.msdn.microsoft.com/How-to-fix-the-routing-225ac90f. But in order to make it work make sure you have this:

app.UseDefaultFiles(new DefaultFilesOptions { DefaultFileNames = new List<string> { "index.html" }});
2
votes

If you're looking for a solution whereby your api is on the same general route e.g. "/api/". And everything else should be routed back to the SPA, then this should work well for you.

app.UseWhen(x => !x.Request.Path.Value.StartsWith("/api"), builder =>
{
    builder.Use(async (context, next) =>
        {
            await next();
            if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
            {
                context.Request.Path = "/index.html";
                await next();
            }
        })
        .UseDefaultFiles(new DefaultFilesOptions {DefaultFileNames = new List<string> {"index.html"}})
        .UseStaticFiles()
        .UseMvc();
});
app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});
2
votes

The answers given here will partially work but also route requests to index.html if your controllers return a 404 (not found). I am using the following code:

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

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

app.UseDefaultFiles(new DefaultFilesOptions { DefaultFileNames = new List<string> { "index.html" }});

This will route all request to index.html, except the ones with extension and api route. Be careful that the api bit is hard-coded and will stop working if you change your resource paths.

0
votes

I'm not sure about .net core 2.0 but this works for me with .net core 1.1 https://github.com/JanneHarju/MultiSourcePlayList/blob/076c6e4108cbae3bb5128e7f176ed35a61593922/Startup.cs#L169

    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();
            }
        });

In my repo there is also that else if part for angular routes but I think there is no more use for it anymore (or maybe ever wasn't).