Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 3, 2025

Add BL0010 analyzer: Recommend InvokeVoidAsync over InvokeAsync
  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

Adds Roslyn analyzer BL0010 to detect InvokeAsync<object> and recommend InvokeVoidAsync

Description

Using InvokeAsync<object> for JS interop calls that don't return a value can cause serialization failures when JavaScript returns non-serializable values (e.g., window). This analyzer catches the antipattern at compile time.

Note: The diagnostic intentionally fires even when the result is assigned to a variable (e.g., var res = await JS.InvokeAsync<object>(...)), because object cannot be properly deserialized from JSON - the result will either be null or cause serialization errors if JavaScript returns a non-serializable value.

Changes:

  • InvokeAsyncOfObjectAnalyzer.cs - Detects InvokeAsync<object> on IJSRuntime, IJSObjectReference, and in-process variants (both direct and extension method calls)
  • DiagnosticDescriptors.cs - Added BL0010 descriptor (Warning, enabled by default)
  • Resources.resx - Localized diagnostic strings
  • InvokeAsyncOfObjectAnalyzerTest.cs - 14 unit tests

Example flagged code:

// BL0010: Use 'InvokeVoidAsync' instead of 'InvokeAsync<object>'
await jsRuntime.InvokeAsync<object>("window.open", url, "_blank");

// Correct
await jsRuntime.InvokeVoidAsync("window.open", url, "_blank");

Fixes #38549

Original prompt

This section details on the original issue you should resolve

<issue_title>Consider Razor Analyzer which Recommends InvokeVoidAsync instead of InvokeAsync<object></issue_title>
<issue_description>Analyzer / Code action pattern for this scenario.

Avoid issues like: #38501 (comment)</issue_description>

Comments on the Issue (you are @copilot in this section)

@ We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our [Triage Process](https://github.com/dotnet/aspnetcore/blob/main/docs/TriageProcess.md). @ We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our [Triage Process](https://github.com/dotnet/aspnetcore/blob/main/docs/TriageProcess.md).

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@dotnet-policy-service
Copy link
Contributor

Greetings! You've submitted a PR that modifies code that is shared with https://github.com/dotnet/runtime . Please make sure you synchronize this code with the changes in that repo!

Copilot AI and others added 2 commits December 3, 2025 09:05
Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
… comparison

Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
Copilot AI changed the title [WIP] Add Razor Analyzer for InvokeVoidAsync recommendation Add BL0010 analyzer: Recommend InvokeVoidAsync over InvokeAsync<object> Dec 3, 2025
Copilot AI requested a review from javiercn December 3, 2025 09:11
Copilot finished work on behalf of javiercn December 3, 2025 09:11
@javiercn javiercn added the area-blazor Includes: Blazor, Razor Components label Dec 3, 2025
@javiercn javiercn marked this pull request as ready for review December 3, 2025 15:47
@javiercn javiercn requested a review from a team as a code owner December 3, 2025 15:47
Copilot AI review requested due to automatic review settings December 3, 2025 15:47
Copilot finished reviewing on behalf of javiercn December 3, 2025 15:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new Roslyn analyzer (BL0010) that detects usage of InvokeAsync<object> in JavaScript interop calls and recommends using InvokeVoidAsync instead. This addresses a common antipattern where developers use InvokeAsync<object> for JS calls that don't return a value, which can lead to serialization failures when JavaScript returns non-serializable values like window or undefined.

Key changes:

  • New analyzer that flags InvokeAsync<object> calls on IJSRuntime, IJSObjectReference, and their in-process variants
  • Comprehensive test coverage with 13 test cases covering various scenarios including extension methods
  • Diagnostic set as a Warning with enabled-by-default behavior

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/Components/Analyzers/src/InvokeAsyncOfObjectAnalyzer.cs Implements the new BL0010 analyzer to detect InvokeAsync<object> calls on JS interop types
src/Components/Analyzers/src/DiagnosticDescriptors.cs Adds the BL0010 diagnostic descriptor with Warning severity
src/Components/Analyzers/src/Resources.resx Adds localized resource strings for the diagnostic title, format, and description
src/Components/Analyzers/test/InvokeAsyncOfObjectAnalyzerTest.cs Provides comprehensive test coverage with 13 test cases for the analyzer

using Microsoft.CodeAnalysis.Operations;

namespace Microsoft.AspNetCore.Components.Analyzers;

Copy link

Copilot AI Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add #nullable enable directive after the namespace declaration to match the coding conventions used in other analyzers in this codebase. This ensures consistent nullable reference type handling across all analyzer files.

Suggested change
#nullable enable

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added #nullable enable directive in commit 61397d9.

Copy link
Member

@oroztocil oroztocil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure the diagnostic will not fire on legitimate cases where the result is not thrown away, e.g.:

var res = await JS.InvokeAsync<object>("...");

There should be tests for these cases.

@javiercn
Copy link
Member

javiercn commented Dec 3, 2025

Are we sure the diagnostic will not fire on legitimate cases where the result is not thrown away, e.g.:

var res = await JS.InvokeAsync<object>("...");

There should be tests for these cases.

@copilot add a test for this if there isn't one. If there is one point out the test name.

Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 3, 2025

Are we sure the diagnostic will not fire on legitimate cases where the result is not thrown away, e.g.:

...

Added test DiagnosticForInvokeAsyncWithObjectReturnAssignedToVariable in commit 61397d9. The diagnostic intentionally fires even when the result is assigned to a variable because using InvokeAsync<object> is problematic regardless - object cannot be properly deserialized from JSON, and the result will either be null or cause serialization errors if JavaScript returns a non-serializable value like window.

Copilot finished work on behalf of javiercn December 3, 2025 18:14
@oroztocil
Copy link
Member

I see, I did not understand the reasoning from the description at first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components Attention: Shared Code Modified

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider Razor Analyzer which Recommends InvokeVoidAsync instead of InvokeAsync<object>

3 participants