Skip to content

Commit

Permalink
.NET assembly packaging (Webcil) (dotnet#29542)
Browse files Browse the repository at this point in the history
  • Loading branch information
guardrex authored and Donciavas committed Feb 7, 2024
1 parent 0e3a0b0 commit 561b92f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 2 deletions.
14 changes: 14 additions & 0 deletions aspnetcore/blazor/host-and-deploy/webassembly-deployment-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,37 @@ uid: blazor/host-and-deploy/webassembly-deployment-layout

[!INCLUDE[](~/includes/not-latest-version.md)]

:::moniker range=">= aspnetcore-8.0"

This article explains how to customize Blazor WebAssembly deployments when the [Webcil packaging format for .NET assemblies is disabled](xref:blazor/host-and-deploy/webassembly#webcil-packaging-format-for-net-assemblies). The app's DLLs are packaged into a multipart bundle file and downloaded together.

:::moniker-end

:::moniker range="< aspnetcore-8.0"

This article explains how to enable Blazor WebAssembly deployments in environments that block the download and execution of dynamic-link library (DLL) files.

Blazor WebAssembly apps require [dynamic-link libraries (DLLs)](/windows/win32/dlls/dynamic-link-libraries) to function, but some environments block clients from downloading and executing DLLs. In a subset of these environments, [changing the file name extension of DLL files (`.dll`)](xref:blazor/host-and-deploy/webassembly#change-the-file-name-extension-of-dll-files) is sufficient to bypass security restrictions, but security products are often able to scan the content of files traversing the network and block or quarantine DLL files. This article describes one approach for enabling Blazor WebAssembly apps in these environments, where a multipart bundle file is created from the app's DLLs so that the DLLs can be downloaded together bypassing security restrictions.

:::moniker-end

A hosted Blazor WebAssembly app can customize its published files and packaging of app DLLs using the following features:

* [JavaScript initializers](xref:blazor/js-interop/index#javascript-initializers) that allow customizing the Blazor boot process.
* MSBuild extensibility to transform the list of published files and define *Blazor Publish Extensions*. Blazor Publish Extensions are files defined during the publish process that provide an alternative representation for the set of files required to run a published Blazor WebAssembly app. In this article, a Blazor Publish Extension is created that produces a multipart bundle with all of the app's DLLs packed into a single file so that the DLLs can be downloaded together.

The approach demonstrated in this article serves as a starting point for developers to devise their own strategies and custom loading processes.

:::moniker range="< aspnetcore-8.0"

> [!WARNING]
> Any approach taken to circumvent a security restriction must be carefully considered for its security implications. We recommend exploring the subject further with your organization's network security professionals before adopting the approach in this article. Alternatives to consider include:
>
> * Enable security appliances and security software to permit network clients to download and use the exact files required by a Blazor WebAssembly app.
> * Switch from the Blazor WebAssembly hosting model to the [Blazor Server hosting model](xref:blazor/hosting-models#blazor-server), which maintains all of the app's C# code on the server and doesn't require downloading DLLs to clients. Blazor Server also offers the advantage of keeping C# code private without requiring the use of web API apps for C# code privacy with Blazor WebAssembly apps.
:::moniker-end

## Experimental NuGet package and sample app

The approach described in this article is used by the *experimental* [`Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle` package (NuGet.org)](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle). The package contains MSBuild targets to customize the Blazor publish output and a [JavaScript initializer](xref:blazor/js-interop/index#javascript-initializers) to use a custom [boot resource loader](xref:blazor/fundamentals/startup#load-boot-resources), each of which are described in detail later in this article.
Expand Down
66 changes: 65 additions & 1 deletion aspnetcore/blazor/host-and-deploy/webassembly.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ The following deployment strategies are supported:
* The Blazor app is placed on a static hosting web server or service, where .NET isn't used to serve the Blazor app. This strategy is covered in the [Standalone deployment](#standalone-deployment) section, which includes information on hosting a Blazor WebAssembly app as an IIS sub-app.
* An ASP.NET Core app hosts multiple Blazor WebAssembly apps. For more information, see <xref:blazor/host-and-deploy/multiple-hosted-webassembly>.

:::moniker range=">= aspnetcore-8.0"

## Webcil packaging format for .NET assemblies

[Webcil](https://github.com/dotnet/runtime/blob/main/docs/design/mono/webcil.md) is a web-friendly packaging format for .NET assemblies designed to enable using Blazor WebAssembly in restrictive network environments. Webcil files use a standard WebAssembly wrapper, where the assemblies are deployed as WebAssembly files that use the standard `.wasm` file extension.

Webcil is the default packaging format when you publish a Blazor WebAssembly app. To disable the use of Webcil, set the following MS Build property in the app's project file:

```xml
<PropertyGroup>
<WasmEnableWebcil>false</WasmEnableWebcil>
</PropertyGroup>
```

:::moniker-end

:::moniker range=">= aspnetcore-6.0"

## Ahead-of-time (AOT) compilation
Expand Down Expand Up @@ -492,6 +508,45 @@ To deploy a Blazor WebAssembly app to CentOS 7 or later:

1. Create the Apache configuration file. The following example is a simplified configuration file (`blazorapp.config`):

:::moniker range=">= aspnetcore-8.0"

```
<VirtualHost *:80>
ServerName www.example.com
ServerAlias *.example.com
DocumentRoot "/var/www/blazorapp"
ErrorDocument 404 /index.html
AddType application/wasm .wasm
<Directory "/var/www/blazorapp">
Options -Indexes
AllowOverride None
</Directory>
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/octet-stream
AddOutputFilterByType DEFLATE application/wasm
<IfModule mod_setenvif.c>
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.0[678] no-gzip
BrowserMatch bMSIE !no-gzip !gzip-only-text/html
</IfModule>
</IfModule>
ErrorLog /var/log/httpd/blazorapp-error.log
CustomLog /var/log/httpd/blazorapp-access.log common
</VirtualHost>
```

:::moniker-end

:::moniker range="< aspnetcore-8.0"

```
<VirtualHost *:80>
ServerName www.example.com
Expand Down Expand Up @@ -526,6 +581,8 @@ To deploy a Blazor WebAssembly app to CentOS 7 or later:
</VirtualHost>
```

:::moniker-end

1. Place the Apache configuration file into the `/etc/httpd/conf.d/` directory, which is the default Apache configuration directory in CentOS 7.

1. Place the app's files into the `/var/www/blazorapp` directory (the location specified to `DocumentRoot` in the configuration file).
Expand Down Expand Up @@ -788,10 +845,17 @@ Blazor performs Intermediate Language (IL) linking on each Release build to remo

## Change the file name extension of DLL files

*This section applies to ASP.NET Core 6.x and 7.x. In ASP.NET Core 8.0 or later, .NET assemblies are deployed as WebAssembly files (`.wasm`) using the Webcil file format. In ASP.NET Core 8.0 or later, this section only applies if the Webcil file format has been disabled in the app's project file.*

If a firewall, anti-virus program, or network security appliance is blocking the transmission of the app's dynamic-link library (DLL) files (`.dll`), you can follow the guidance in this section to change the file name extensions of the app's published DLL files.

> [!NOTE]
> Changing the file name extensions of the app's DLL files might not resolve the problem because many security systems scan the content of the app's files, not merely check file extensions. For a more robust approach in environments that block the download and execution of DLL files, see <xref:blazor/host-and-deploy/webassembly-deployment-layout>.
> Changing the file name extensions of the app's DLL files might not resolve the problem because many security systems scan the content of the app's files, not merely check file extensions.
>
> For a more robust approach in environments that block the download and execution of DLL files, take ***either*** of the following approaches:
>
> * Use ASP.NET Core 8.0 or later, which by default packages .NET assemblies as WebAssembly files (`.wasm`) using the [Webcil](https://github.com/dotnet/runtime/blob/main/docs/design/mono/webcil.md) file format. For more information, see the *Webcil packaging format for .NET assemblies* section in an 8.0 or later version of this article.
> * In ASP.NET Core 6.0 or later, use a [custom deployment layout](xref:blazor/host-and-deploy/webassembly-deployment-layout).
>
> Third-party approaches exist for dealing with this problem. For more information, see the resources at [Awesome Blazor](https://github.com/AdrienTorris/awesome-blazor).
Expand Down
2 changes: 1 addition & 1 deletion aspnetcore/blazor/progressive-web-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ By default, this manifest lists:
* Any Blazor-managed resources, such as .NET assemblies and the .NET WebAssembly runtime files required to function offline.
* All resources for publishing to the app's `wwwroot` directory, such as images, stylesheets, and JavaScript files, including static web assets supplied by external projects and NuGet packages.

You can control which of these resources are fetched and cached by the service worker by editing the logic in `onInstall` in `service-worker.published.js`. By default, the service worker fetches and caches files matching typical web file name extensions such as `.html`, `.css`, `.js`, and `.wasm`, plus file types specific to Blazor WebAssembly (`.dll`, `.pdb`).
You can control which of these resources are fetched and cached by the service worker by editing the logic in `onInstall` in `service-worker.published.js`. By default, the service worker fetches and caches files matching typical web file name extensions such as `.html`, `.css`, `.js`, and `.wasm`, plus file types specific to Blazor WebAssembly, such as `.pdb` files (all versions) and `.dll` files (ASP.NET Core 7.0 or earlier).

To include additional resources that aren't present in the app's `wwwroot` directory, define extra MSBuild `ItemGroup` entries, as shown in the following example:

Expand Down

0 comments on commit 561b92f

Please sign in to comment.