Skip to content

[Validation] Analyzer diagnostics for JavaScript interop #68483

Description

@oroztocil

Scenario contact: @ilonatommy, @MayaKirova, @kdinev, @skrustev, @damyanpetev

Scenario

JavaScript interop is one of the easiest places in Blazor to write code that compiles cleanly and then fails at runtime: calling into JavaScript before the browser is there, returning a value the app cannot deserialize, or exposing a .NET method to JavaScript that JavaScript is unable to reach. This validates that the build now points these problems out while the code is being written, that the guidance is correct, and that it stays quiet for interop code that is written properly.

Minimum build

.NET 11 Preview 7 or later.

Configurations to cover

  • Blazor Web App
    • Static SSR
    • Interactive Server
    • Interactive WebAssembly
    • Interactive Auto
  • Standalone WebAssembly
  • Hybrid (MAUI)

These diagnostics are produced by the compiler, so they do not vary by render mode. The configuration below is the one needed to reproduce the runtime behavior the warning predicts, not a matrix to work through. Static SSR is included because prerendering is what makes the BL0016 runtime failure reproducible.

Also exercise

  • Published output
  • An existing .NET 10 app upgraded to .NET 11
  • Trimming or ahead-of-time compilation
  • More than one server instance, or a proxy in front
  • Hot Reload
  • An IDE as well as the command line
  • Container

Setup

Work in an IDE as well as at the command line. Part of what is being tested is whether the guidance appears while typing and whether the offered fixes apply cleanly.

The three diagnostics this scenario covers are:

Id Title Code fix
BL0010 Use InvokeVoidAsync instead of InvokeAsync<object> No
BL0015 [JSInvokable] methods should be public Yes
BL0016 Unguarded JS interop call Yes

What to build

An app with a component that talks to JavaScript in several ways, written first the way a developer might do it without thinking too hard. Call a JavaScript function that returns nothing, but ask for a result anyway. Expose a .NET method to JavaScript for a callback, and declare it without making it reachable. Call into JavaScript from a lifecycle method that also runs while the page is being prerendered, without protecting against the call failing. Alongside these, write the same kinds of interop correctly as well, so you can see whether the build stays quiet about code that is already right. Write some of this in a component file and some in a plain class, since both are ordinary places for interop code to live.

Things to try

  • Building at the command line and reading the messages that appear.
  • Opening the same code in an IDE and comparing what is shown there.
  • Applying the offered automatic fixes for BL0015 and BL0016, and rebuilding.
  • Applying a fix to a method that already has several modifiers on it, and to one written in a component file rather than a plain class.
  • Running the app afterwards to confirm the corrected interop actually works.
  • Writing interop that is already correct in a few different shapes to see whether any of them are flagged unnecessarily.
  • Deliberately keeping one problem in place and running the app, to see the runtime failure the guidance was warning about. The report behind BL0016 names three contexts where interop can fail: prerendering, Interactive Server when the circuit has dropped, and a WebView. Prerendering is the easiest to reproduce here; if you have a Hybrid app to hand, try it there too.
  • Building the same code in the server project, in the .Client project, and in a Razor Class Library, confirming the warnings appear in all three. The analyzer reaches these through different routes, one bundled in the SDK and one flowing through the Microsoft.AspNetCore.Components package.

Expected behavior

Each mistake is reported at build time with advice that is correct, and correct interop is left alone.

Must hold

  • Each deliberately wrong piece of interop produces a build warning carrying the expected identifier from the table above, at the correct line.
  • The same warnings appear both at the command line and in the IDE, with the same identifiers and counts.
  • The same warnings appear whether the code is built in the server project, the .Client project, or a Razor Class Library.
  • Applying the BL0015 and BL0016 code fixes produces code that compiles, keeps the surrounding modifiers and formatting intact, and works when the app runs.
  • The correctly written interop produces none of these warnings.
  • Running the app with one problem left in place reproduces the runtime failure the message described.

Expected differences between configurations

  • The warnings themselves are identical everywhere, because they are produced at compile time.
  • Only the runtime failure behind BL0016 differs: it needs a configuration that renders on the server before the browser takes over, which is why static SSR is covered here.

Documentation to use

What to report

Report results using the format described in the validation testing manual. Include link to a repository with the test app.

Metadata

Metadata

Labels

ValidationThis issue is used to track validation effortsarea-blazorIncludes: Blazor, Razor Componentsvalidation-scenarioThis issue describes a validation testing scenario

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions