6

I have an existing MVC project and I am trying to integrate Blazor into it. To do this I had to upgrade from .NET Core 2.1 to 3.1 and change a few things in my startup class to get the application working as it was before.

After sorting all the upgrade stuff out, I've now added the hub to my Configure startup method:

...

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "areas",
        pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");

    endpoints.MapControllers();
    endpoints.MapRazorPages();
    endpoints.MapBlazorHub();
});

... and the server sign Blazor services registration:

...

services
    .AddMvc(options =>
    {
        ...
    })
    .AddRazorOptions(o =>
    {
        ...
    })
    .AddRazorPagesOptions(options =>
    {
        ...
    });

services.AddServerSideBlazor();

Finally, I've added the Blazor JS script to my ~/Pages/Shared/_Layout.cshtml view:

<script src="~/_framework/blazor.server.js"></script>

I'm struggling to figure out what the @page value should be for a new Razor Component when the component is within a view.

Here is my folder structure:

enter image description here

Everything inside the Pages folder is new.

Here is the contents of Index.razor:

@page "/"

<h3>Sales Homepage</h3>

@code {

}

I've tried the following for the @page route value:

  • "/"
  • "/Index"
  • "/Pricing/Sales/"
  • "/Pricing/Sales/Index"

None of these have worked - I just get a page not found error.

I'm also not sure how I'm supposed to use my existing layout in ~/Pages/Shared/_Layout.cshtml with these new components.

I've had a look at the scaffolded Blazor template project in Visual Studio and also checked the docs but haven't found this particularly useful as it's all focused on brand new Blazor projects.

Andy Furniss
  • 3,814
  • 6
  • 31
  • 56

2 Answers2

9

To add blazor pages support, you also need to add call to MapFallbackToPage (for Razor Pages project) or MapFallbackToController(for MVC project) in startup endpoint configuration.

For MVC project, refer to below steps:

1.Create a App.razor under Views folder

@using Microsoft.AspNetCore.Components.Routing

<Router AppAssembly="typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="routeData" />
    </Found>
    <NotFound>
        <h1>Page not found</h1>
        <p>Sorry, but there's nothing here!</p>
    </NotFound>
</Router>

2.Create a _Host.cshml file under Views/Shared

@page "/blazor"

@{
    Layout = "_Layout";
}

<app>
    @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
</app>

MyApp

——Views

————Shared

——————Host.cshtml

————App.razor

3.Add call to MapFallbackToController and point it to the new _Host.cshtml:

app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            endpoints.MapRazorPages();
            endpoints.MapBlazorHub();
            endpoints.MapFallbackToController("Host","Home");
        });

HomeController:

public class HomeController : Controller
{
    public IActionResult Host()
    {
        return View("_Host");
    }
}

4.Index.razor test with "/"

@page "/"

<h3>Sales Homepage</h3>

For Razor Pages project, just create _Host.cshtml and App.razor under Pages folder, and use endpoints.MapFallbackToPage("/_Host") in startup.cs

More clear steps,refer to https://mikaelkoskinen.net/post/combining-razor-blazor-pages-single-asp-net-core-3-application

Community
  • 1
  • 1
Ryan
  • 19,118
  • 10
  • 37
  • 53
  • Thanks. I have made progress and can now see my Sales component content under `Pricing/Sales`. However, if I change something in the razor component and refresh the page, nothing changes. Any ideas? – Andy Furniss Jan 13 '20 at 18:10
  • @Andy Furniss Do you change the component without rebuilding the project?blazor does not support live reloading with debugger(F5) but without debugger (ctrl-F5) works.https://stackoverflow.com/questions/58861948/browser-link-not-refreshing-page-in-chrome/58871880#58871880 – Ryan Jan 14 '20 at 01:35
  • Thank you. No debugger and ctrl+F5 seems to work as you say. However, before I hit ctrl+F5, I get the following error in the console `Connection disconnected with error 'Error: WebSocket closed with status code: 1006 ().` which suggests it's trying to live reload but failing. Is this something else I can fix? – Andy Furniss Jan 14 '20 at 09:09
  • Does this work for Static Web App? seems to fail deploying onto Azure static web app – Marin Apr 29 '21 at 09:02
2

You must:

  1. Define another namespace for Areas/Pages to prevent name conflict with main branch without Areas.

  2. Place to you Areas new App.razor component. The same if layout is the same.

  3. Place your page with @route attribute on top of each page in Areas/Pages and Areas/Shared

  4. Place _Host.rasor, the same if layout is the same. But you must changing href attibutes in header (add ~).

  5. Add to startup new route

endpoints.MapAreaControllerRoute("admin_route", "Admin", "Admin/{controller}/{action}/{id?}");
  1. Main point to hope to Areas is: you must break existing SignalR connection and navigate to Areas not from simple click, but the same way
navigationManager.NavigateTo("/Admin/", forceLoad: true);

This is workable pattern, I always use it and it working fine.

Matt Ke
  • 3,599
  • 12
  • 30
  • 49
Viacheslav
  • 1,054
  • 12
  • 16
  • Could you please. Give us more details, your answer seems very interesting to me. –  Jul 09 '22 at 22:53