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:
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";
}
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With