7

Have a Web Forms app that I would like to gradually port, on a page by page basis, to Blazor WebAssembly by embedding Blazor into Web Form pages the way it is possible with Angular.

Published the Blazor app to the Web Forms project under a subdirectory called "Blazor". If I run the Web Forms app and hit http://localhost:1234/Blazor the Blazor app runs fine (after editing the Blazor index.html => <base href="/Blazor/" />). However, when I try to embed Blazor in a Web Form page it doesn't work. The web form page asp:content contains what the Blazor index.html page contains:

<%@ Page Title="EmbedTest" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="EmbedTest.aspx.cs" Inherits="WebFormBlazor.EmbedTest" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <app>Loading...</app>

    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a> 
    </div>

    <script src="/Blazor/wwwroot/_framework/blazor.webassembly.js"></script>
</asp:Content>

When I go to http://localhost:1234/EmbedTest the page displays: Loading... An unhandled error has occurred. Reload 🗙

And in the console the following error message: Uncaught SyntaxError: Unexpected token '<' blazor.webassembly.js:1

This approach does work with Angular. What am I missing in trying to do this with Blazor WebAssembly?

Update: As per Mister Magoo, it was not downloading blazor.webassembly.js but actually downloading the index.html which explains the error message.

Changed the path in the page from /Blazor/wwwroot/_framework/blazor.webassembly.js to /Blazor/_framework/blazor.webassembly.js in the Web Form page and now downloads the script but experiences new error. Gives 404 Not Found for blazor.boot.json.

Blazor.webassembly.js doesn't know the base href should be /Blazor/ and tries to fetch blazor.boot.json from localhost:1234/_framework/blazor.boot.json instead of localhost:1234/Blazor/_framework/blazor.boot.json.

So next issue: How to tell blazor.webassembly.js that its base href should be something other than '/' (in my case '/Blazor/')?

3
  • Check the network tab when you load the page - does the blazor.webassembly.js file get served correctly? (My guess is no because the path looks odd - remove wwwroot) Commented Dec 31, 2020 at 11:54
  • Yes, all the necessary files get served with http status 200 including blazor.webassembly.js Commented Dec 31, 2020 at 14:56
  • But is it actually returning the correct file, not just the correct status? Can you download it manually? Commented Dec 31, 2020 at 15:17

2 Answers 2

6

Got a proof-of-concept working:

  1. Generated the default Blazor WebAssembly project.
  2. Built the project and copied the output _framework directory and its contents into the Web Forms project.
  3. Added the following from the Blazor web.config to the Web Forms web.config:
  <system.webServer>
    <staticContent>
      <remove fileExtension=".dat" />
      <remove fileExtension=".dll" />
      <remove fileExtension=".json" />
      <remove fileExtension=".wasm" />
      <mimeMap fileExtension=".dll" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".dat" mimeType="application/octet-stream" />
      <mimeMap fileExtension=".json" mimeType="application/json" />
      <mimeMap fileExtension=".wasm" mimeType="application/wasm" />
    </staticContent>
    <httpCompression>
      <dynamicTypes>
        <add mimeType="application/octet-stream" enabled="true" />
        <add mimeType="application/wasm" enabled="true" />
      </dynamicTypes>
    </httpCompression>
  </system.webServer>
  1. Edited the contents of the Counter.aspx Web Form page to be:
<%@ Page Title="Counter" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="false" CodeBehind="Counter.aspx.cs" Inherits="WebFormBlazor.Counter" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <app></app>

    <script src="_framework/blazor.webassembly.js"></script>
</asp:Content>
  1. Edited the Blazor MainLayout.razor to just:
@inherits LayoutComponentBase
<div>
    @Body
</div>
  1. Run the Web Forms project and go to http://localhost:1234/Counter and the Web Form Counter page comes up with the Blazor Counter page embedded.
Sign up to request clarification or add additional context in comments.

2 Comments

I have now a similar issue. We need to rewrite and old ASP.NET Framework 4.7 WebForms application sort of page by page. So I want to host the new components in ASPX pages. Do you have a code sample what you did exactly please? Because I'm lost how are you referencing .NET Core projects which has Blazor components into .NET Framework 4.7?? Thanks.
Hmm reading it 5 times now I get it :) so you basically created a "child site" which is Blazor WebAssembly app. And basically you have <app></app> and Blazor setup on every page where you want ot use it So Blazor routing not used at all.... Question here don't you get horrible performance since Blazor app has to initialized on each page?
0

If you want anything more complex than just one blazor page inside one web forms page I suggest you use an iframe to host the blazor app inside your web forms app. This will make them independent and you don't run the risk of fetching assets twice, and/or getting invalid HTML and/or DOM manipulations on the webforms page to hurt the blazor app.

Generally, you should also keep in mind that WebForms does not run on .NET Core (or .NET 5 and later), while Blazor runs only on .NET Core 3 or .NET 5 (or later) so this mix of technologies can bite you later.

If you want to move page by page and you won't have anything else but the blazor app - the PoC above should work out as soon as you can ensure correct paths and base paths (if you have folders in your webforms app this could throw off the blazor routing and paths). Moreover, firing up the wasm app is slow for the client, so you may want to consider a server-side blazor page instead (which will require an iframe for sure).

EDIT: You may find useful this book MS are making for WebForms -> Blazor migration https://learn.microsoft.com/en-us/dotnet/architecture/blazor-for-web-forms-developers/

7 Comments

Could you use Blazor Server to host a WebForm page that one could call in an iframe in a blazor component?
Yes, I see no reason why you should not be able to frame your page. Of course config like x-frame-options and the like can apply, but tblazor can work with iframes
"Generally, you should also keep in mind that WebForms does not run on .NET Core (or .NET 5 and later), while Blazor runs only on .NET Core 3 or .NET 5 (or later) so this mix of technologies can bite you later." - That comment kind of misses the point... The Blazor web assembly runs on the client, presumably it consumes an API hosted elsewhere, so the fact that webforms is running on 4.7 (on the server) and the Blazor App is running on .Net 5 (on the client) is irrelevant. As a development strategy it's not a good idea for a new project, but as a migration strategy it makes sense.
Building one of very different to building the other. So this mix can start causing trouble in the pipeline, not necessarily in the app code. Just a consideration.
you just need to host both apps separately (e.g., their own web sites or web applications, or servers, what have you) and then an <iframe> in one has its src attribute point to the desired page in the other.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.