Search code examples
asp.net-core.net-corerazor-pagesasp.net-core-2.2asp.net-core-routing

Changing the default landing page in ASP.NET Core Razor page?


I tried:

services.AddMvc().AddRazorPagesOptions(options =>
{
    options.Conventions.AddPageRoute("/Index", "old");
    options.Conventions.AddPageRoute("/NewIndex", "");
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

This exception is thrown:

AmbiguousMatchException: The request matched multiple endpoints. Matches:

Page: /Index

Page: /NewIndex

I found this, that suggests renaming the Index page, but it obviously, if not a good reason presented, is a workaround. Can't I just change the default page without renaming the /Index page?

EDIT

The suggested SO threads don't cover the problem I explained, which is overriding the default route without having to rename the default Index page. The accepted answer solved the problem.


Solution

  • Default pages in Razor Pages are those that have an empty string route template generated for them. You can use a custom PageRouteModelConvention to remove the empty string route template that gets generated for the Index.cshtml page, and add it instead to whichever page you want as your default page:

    public class HomePageRouteModelConvention : IPageRouteModelConvention
    {
        public void Apply(PageRouteModel model)
        {
            if(model.RelativePath == "/Pages/Index.cshtml")
            {
                var currentHomePage = model.Selectors.Single(s => s.AttributeRouteModel.Template == string.Empty);
                model.Selectors.Remove(currentHomePage);
            }
    
            if (model.RelativePath == "/Pages/NewIndex.cshtml")
            {
                model.Selectors.Add(new SelectorModel()
                {
                    AttributeRouteModel = new AttributeRouteModel
                    {
                        Template = string.Empty
                    }
                });
            }
        }
    }
    

    You register the convention in ConfigureServices:

    services.AddMvc().AddRazorPagesOptions(options =>
    {
        options.Conventions.Add(new HomePageRouteModelConvention());
    }).SetCompatibilityVersion(CompatibilityVersion.Latest);
    

    You can read more about custom page route model conventions here: https://www.learnrazorpages.com/advanced/custom-route-conventions