Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extend an ASP.NET Core MVC project by Razor Pages?

I'm currently trying to extend an existing ASP.NET Core MVC project by a Razor page (since several tutorial videos claim that MVC, API, Razor and Blazor can coexist in the same project - but none of them shows how it's done).

I already figured out I need to extend Startup.cs by

services.AddRazorPages();

and

app.UseEndpoints(endpoints =>
{
    // This was here already
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    // I added this
    endpoints.MapRazorPages();
});

I tried simply adding a razor page "Test" to the Views folder, extending the _Layout.cshtml by

<li class="nav-item">
    <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Test">Test</a>
</li>

then extending HomeController by

    public IActionResult Test()
    {
        return View();
    }

However, this causes several issues with breakpoints not being hit, or the ViewData dictionary being null (with the identical code working in a pure Razor Page project), probably since it tries treating the Razor Page as an MVC view or something.

I've also tried adding something like

<li class="nav-item">
    <a class="nav-link text-dark" asp-area="" asp-page="/Home/Test">Test</a>
</li>

to the layout instead, but this produces an URL like

https://localhost:5001/?page=%2FHome%2FTest

when clicking the navbar item.

I can perfectly have both things in separate VS projects, but isn't there a way to use both of them in a single VS project and a single layout?

If you want to try it out before answering, use the following steps:

  1. Create a new project/solution in Visual Studio 2019
  2. Select "ASP.NET Core Web Application" as project template
  3. Click "Create" and select "Web Application (Model-View-Controller)" as template with default settings
  4. Add Razor Support in Startup.cs
  5. Try to make a simple razor page working in this project
like image 612
Tim Meyer Avatar asked Jul 12 '20 15:07

Tim Meyer


2 Answers

The razor pages does not requires a controller.

The default directory is /Pages, then by default all pages should be inside Pages directory. If you want to change it you can do it by overriding the configuration in ConfigureServices on startup.

services.AddRazorPages(c=>c.RootDirectory = "/PagesRootDir");

To create a link to page, you should use asp-page tag. For example, if the page name is Test the physical path (by default) will be Pages\Test. To generate the link, you will need to use:

<a asp-page="/Test">Test Page</a>

By default the pages won't use the default layout, you can always override it.

@page
@model WebApplication1.Pages.TestModel
@{
    Layout = "_Layout";
}

<h1>
    Test Page
</h1>

To remove the layout:

Layout = null;

If you want to use the "Views\Shared\_Layout" on all the pages, you will need to create a _ViewStart with the following code:

@{
    Layout = "_Layout";
}

enter image description here

like image 67
dbvega Avatar answered Oct 23 '22 17:10

dbvega


I've found a solution which seems to work for now: In Startup.cs, configure razor pages to look in the /Views folder instead of it's default /Pages (this obviously breaks convention):

services.AddRazorPages(configure => configure.RootDirectory = "/Views");

Using this, I can use the asp-page-style nav item without adapting the controller.

I will still accept anyone's answer if you can show me how to do this without breaking default conventions (My main issue is I have no idea how to make this work with a Pages folder, a Views folder and the _Layout.cshtml being in only one of them.)

like image 1
Tim Meyer Avatar answered Oct 23 '22 19:10

Tim Meyer