6

NOTE: This is a "Share your knowledge - Q&A style" post. I probably got a downvote because someone misinterpreted the context of this post :(

Problem

Blazor WASM could've been easily preferred over Blazor Server-Side without its downsides development-wise. Currently, Blazor WASM doesn't support a full-featured debugging experience and has a very slow startup. This slows down development much more than with Blazor Server-Side. Though I honestly personally think that the debugging experience slows down the development much more than the slow startup.

Proposed Solution

NOTE: I included the "proposed" word in there because I'm not sure about the downsides that this solution can cause, so feel free to comment on my answer below.

The solution is to simply create an additional Blazor Server-Side project then reference the Blazor WASM project to the Blazor Server-Side project. Afterwards, add some tweaks to the Startup and the _Host.cshtml of the Blazor Server-Side to properly use the Blazor WASM razor files and the wwwroot files. See my proposed answer below for a step-by-step explanation for this solution.

In simpler terms, this solution just adds and configures the Blazor Server-Side project without making any changes and any significant code duplication to the Blazor WASM project.

DaaWaan
  • 441
  • 2
  • 16

1 Answers1

9

NOTE: In this example, I'm using Visual Studio 2019 16.7.2 and the version of the templates are currently at 3.1.8

  1. Create a Blazor WASM project. Either the ASP.NET Core Hosted or the Standalone option will work fine but they will have different configurations later that will be discussed. The rest of the options won't have any effect. In this example, I'll go with the ASP.NET Core Hosted to explain later about having API Controllers. Also create the Blazor Server-Side project afterwards.

    Create ASP.NET Core Hosted Blazor WASM Project Create Blazor Server-Side project


  1. As of this moment, your project structure should be similar to the first screenshot below.

    Delete the highlighted items in the Blazor Server-Side project shown in the second screenshot below.

    enter image description here Items to remove from the Blazor Server-Side project


  1. Reference the Blazor WASM project to the Blazor Server-Side project.

    • ASP.NET Core Hosted - Reference both the BlazorWasm.Client & BlazorWasm.Server project.
    • Standalone - Reference the single Blazor WASM project as is.

  1. Go to the Startup class of the Blazor Server-Side project. In the ConfigureServices(), remove the WeatherForecastService together with the BlazorServer.Data namespace then add a service for the HttpClient to be used by the razor files from the Blazor WASM project.

    services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(sp.GetRequiredService<NavigationManager>().BaseUri) });
    

    NOTE In production, I don't suggest creating an instance of the HttpClient. Use the IHttpClientFactory instead. Visit this article Use IHttpClientFactory to implement resilient HTTP requests.

    For ASP.NET Core WASM Projects

    In the Configure(), map the controllers' endpoints. This will use the controllers in the X.Server/BlazorWasm.Server project.

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        ...
    });
    

  1. Go to the _Host.cshtml in the /Pages folder of the Blazor Server-Side project. Change the reference of the css/site.css to css/app.css since the filenames for the main css file for the Blazor WASM project are different.

    <link href="css/site.css" rel="stylesheet" /> <!-- Previous -->
    <link href="css/app.css" rel="stylesheet" /> <!-- New -->
    

  1. Lastly, change the App in the type attribute of the component tag and refer to the App razor class file in the Blazor WASM project. In this example, the App class is found in the BlazorWasm.Client project:

    <component type="typeof(App)" render-mode="ServerPrerendered" /> <!-- Previous -->
    <component type="typeof(BlazorWasm.Client.App)" render-mode="ServerPrerendered" /> <!-- New -->
    

That's it! When you run the Blazor Server-Side project, it should load without the "Loading ..." text.

  • No changes made to the Blazor WASM project(s) and no significant code duplication made.
  • The only things to change are the references and the launchSettings.json & appsettings.json.
  • As for the configurations in the Startup for the Blazor Server-Side, you can just create extension methods in the Blazor WASM project(s) and use them in the Blazor Server-Side project.

NOTE: I honestly think this is ideally(?) only for debugging during development since the WASM razor files won't fully utilize the capability of a true Blazor Server-Side because it would still use HTTP Requests.

Blazor WASM Project running as Blazor Server-Side


Hoping for feedbacks down below! :DD

DaaWaan
  • 441
  • 2
  • 16
  • How can one handle authentication in this case? – Mihaimyh Sep 10 '20 at 10:47
  • Thanks! This works a treat, and definitely makes the development experience far more pleasurable. The standard WASM launch/debugging experience takes absolutely ages and is basically unusable, but then again I'm only using an Core i7, so hopefully MS fixes it soon. – Gordon Rudman Sep 12 '20 at 15:58
  • @Gordon Rudman True. Though .NET 5 release is already near and hoping that there are improvements in development experience, in the meantime we can do this. – DaaWaan Sep 12 '20 at 16:04
  • @Mihaimyh Pardon for the late reply, I don't think running Blazor WASM as Blazor Server-Side would affect authentication. Educate me if I'm probably missing something. – DaaWaan Sep 12 '20 at 16:18