Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.
This repository was archived by the owner on Apr 8, 2020. It is now read-only.

Purpose of MapSpaFallbackRoute #973

Closed

Description

@im1dermike

What is the purpose of the following code which is automatically loaded to the Startup class with this project:

routes.MapSpaFallbackRoute(
    name: "spa-fallback",
    defaults: new { controller = "Home", action = "Index" });

This results in a 200 being thrown when a non-existent API endpoint is hit instead of a 404.

Activity

  1. MarkPieszak commented on May 24, 2017

    @MarkPieszak
    Contributor

    It's for when you want to handle the 404 within your front-end application (and as noted below, let all Routes go through so your front-end can handle them)

  2. im1dermike commented on May 24, 2017

    @im1dermike
    Author

    @MarkPieszak My use case - which I assume is very common - is to want to handle bad angular routes in the front-end (by either sending to a "404" routes or just loading a "home" route), but throw 404s on bad API calls (that is, requests whose URL follows a certain pattern eg. "/api").

    Can you give me a recommendation?

  3. MarkPieszak commented on May 24, 2017

    @MarkPieszak
    Contributor

    You want to use a mapWhen looking for something that starts with /api, use this below and you'll be all set:

               // this part you already have
               app.UseMvc(routes =>
                {
                    routes.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}");
                });
    
                // here you can see we make sure it doesn't start with /api, if it does, it'll 404 within .NET if it can't be found
                app.MapWhen(x => !x.Request.Path.Value.StartsWith("/api"), builder =>
                {
                    builder.UseMvc(routes =>
                    {
                        routes.MapSpaFallbackRoute(
                            name: "spa-fallback",
                            defaults: new { controller = "Home", action = "Index" });
                    });
                });

    Hope that helps!

  4. SteveSandersonMS commented on May 24, 2017

    @SteveSandersonMS
    Member

    Thanks @MarkPieszak for the answer. If this becomes a common request, we could add a further excludePrefix option onto MapSpaFallbackRoute so you can set it to api.

  5. SteveSandersonMS commented on May 24, 2017

    @SteveSandersonMS
    Member

    Also:

    It's for when you want to handle the 404 within your front-end application.

    That's not the whole story. It's mostly just so that all URLs that might be handled by your front-end application cause the front-end application to be returned. For example, a request for the URL /counter (in the default template) should cause the front-end application to be loaded, which will then display a suitable UI. If you didn't have MapSpaFallbackRoute then the server would just return a 404 for /counter since there's no matching MVC controller.

  6. im1dermike commented on May 24, 2017

    @im1dermike
    Author

    @MarkPieszak Perfect. Your solution works as desired.

    Fantastic responsiveness as usual.

  7. ADefWebserver commented on May 24, 2017

    @ADefWebserver

    If you didn't have MapSpaFallbackRoute then the server would just return a 404 for /counter since there's no matching MVC controller.

    So umm yeah, this is REALLY an important point that I hope does not get lost :)

    Meaning. I can send someone a url like this:

    http://helloworlddata.azurewebsites.net/counter

    ..and it works even though there is really no /counter page. It exists only as an Angular route :)

  8. MarkPieszak commented on May 24, 2017

    @MarkPieszak
    Contributor

    That's not the whole story. It's mostly just so that all URLs that might be handled by your front-end application cause the front-end application to be returned. For example, a request for the URL /counter (in the default template) should cause the front-end application to be loaded, which will then display a suitable UI. If you didn't have MapSpaFallbackRoute then the server would just return a 404 for /counter since there's no matching MVC controller.

    Yes apologies I should of mentioned that! @SteveSandersonMS

  9. buvinghausen commented on Sep 9, 2017

    @buvinghausen

    For anyone who wants to use ASP.NET Razor Pages that came out with .NET Core 2.0 I never could get map fallback route to work so I pivoted and went a different direction which implements @MarkPieszak 's solution of only routing all requests to the SPA when the route doesn't start with API.

    public void ConfigureServices(IServiceCollection services) =>
      services
        .AddMvc()
        .AddRazorPagesOptions(options =>
        {
          options.Conventions.AddPageRoute("/Index", "{*url:regex(^(?!api).*$)}");
        });
  10. pholly commented on Oct 25, 2017

    @pholly

    @buvinghausen That works well. Just be aware that every request that doesn't match a static file will get routed to your SPA - even requests with file extensions. MapSpaFallbackRoute does not match requests that look like filenames - that is, have an extension at the end.

    Edit: I just realize you do account for periods in the request - but I'll leave my comment here just in case it helps others. Thanks!

    Edit2: Just opened an issue with https://github.com/aspnet/JavaScriptServices with a suggestion: #1354

  11. ripasfilqadar commented on Apr 5, 2018

    @ripasfilqadar
     app.UseMvc(routes =>
                    {
                        routes.MapSpaFallbackRoute(
                        name: "spa-fallback-admin",
                        defaults: new { area="Admin", controller = "Home", action = "Index" });
                    });
    

    is this the correct way to using controller from some areas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      ⌂ Proxy