Skip to content

Commit ae7e20c

Browse files
authored
Add some notes about JSInterop limits (#20185)
1 parent f52a0cf commit ae7e20c

1 file changed

Lines changed: 30 additions & 2 deletions

File tree

aspnetcore/blazor/call-javascript-from-dotnet.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,10 @@ The placeholder `{APP ASSEMBLY}` is the app's app assembly name (for example, `B
148148

149149
## Call a void JavaScript function
150150

151-
JavaScript functions that return [void(0)/void 0](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/void) or [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined) are called with <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync%2A?displayProperty=nameWithType>.
151+
Use <xref:Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync%2A?displayProperty=nameWithType> for the following:
152+
153+
* JavaScript functions that return [void(0)/void 0](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/void) or [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined).
154+
* If .NET isn't required to read the result of a JavaScript call.
152155

153156
## Detect when a Blazor Server app is prerendering
154157

@@ -649,8 +652,33 @@ Additionally, the preceding example shows how it's possible to encapsulate JavaS
649652

650653
::: moniker-end
651654

655+
## Size limits on JS interop calls
656+
657+
In Blazor WebAssembly, the framework doesn't impose limits on the size of inputs and outputs of JS interop calls.
658+
659+
In Blazor Server, the result of a JS interop call is limited by the maximum payload size enforced by SignalR (<xref:Microsoft.AspNetCore.SignalR.HubOptions.MaximumReceiveMessageSize>), which defaults to 32 KB. Applications that attempt to respond to a JS interop call with a payload larger than <xref:Microsoft.AspNetCore.SignalR.HubOptions.MaximumReceiveMessageSize> throw an error. A larger limit can be configured by modifying <xref:Microsoft.AspNetCore.SignalR.HubOptions.MaximumReceiveMessageSize>. The following example sets the maximum receive message size to 64 KB (64 * 1024 * 1024):
660+
661+
```csharp
662+
services.AddServerSideBlazor()
663+
.AddHubOptions(options => options.MaximumReceiveMessageSize = 64 * 1024 * 1024);
664+
```
665+
666+
Increasing the SignalR limit comes at the cost of requiring the use of more server resources, and it exposes the server to increased risks from a malicious user. Additionally, reading a large amount of content in to memory as strings or byte arrays can also result in allocations that work poorly with the garbage collector, resulting in additional performance penalties. One option for reading large payloads is to consider sending the content in smaller chunks and processing the payload as a <xref:System.IO.Stream>. This can be used when reading large JSON payloads or if data is available in JavaScript as raw bytes. For an example that demonstrates sending large binary payloads in Blazor Server that uses techniques similar to the `InputFile` component, see the [Binary Submit sample app](https://github.com/aspnet/samples/tree/master/samples/aspnetcore/blazor/BinarySubmit).
667+
668+
Consider the following guidance when developing code that transfers a large amount of data between JavaScript and Blazor:
669+
670+
* Slice the data into smaller pieces, and send the data segments sequentially until all of the data is received by the server.
671+
* Don't allocate large objects in JavaScript and C# code.
672+
* Don't block the main UI thread for long periods when sending or receiving data.
673+
* Free any memory consumed when the process is completed or cancelled.
674+
* Enforce the following additional requirements for security purposes:
675+
* Declare the maximum file or data size that can be passed.
676+
* Declare the minimum upload rate from the client to the server.
677+
* After the data is received by the server, the data can be:
678+
* Temporarily stored in a memory buffer until all of the segments are collected.
679+
* Consumed immediately. For example, the data can be stored immediately in a database or written to disk as each segment is received.
680+
652681
## Additional resources
653682

654683
* <xref:blazor/call-dotnet-from-javascript>
655684
* [InteropComponent.razor example (dotnet/AspNetCore GitHub repository, 3.1 release branch)](https://github.com/dotnet/AspNetCore/blob/release/3.1/src/Components/test/testassets/BasicTestApp/InteropComponent.razor)
656-
* [Perform large data transfers in Blazor Server apps](xref:blazor/advanced-scenarios#perform-large-data-transfers-in-blazor-server-apps)

0 commit comments

Comments
 (0)