Wywoływanie metod platformy .NET z funkcji Języka JavaScript w programie ASP.NET Core Blazor
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
W tym artykule wyjaśniono, jak wywoływać metody platformy .NET z poziomu języka JavaScript (JS).
Aby uzyskać informacje na temat wywoływania JS funkcji z platformy .NET, zobacz Wywoływanie funkcji JavaScript z metod platformy .NET w programie ASP.NET Core Blazor.
Wywoływanie statycznej metody platformy .NET
Aby wywołać statyczną metodę .NET z języka JavaScript (JS), użyj JS funkcji:
DotNet.invokeMethodAsync
(zalecane): Asynchroniczne dla składników po stronie serwera i po stronie klienta.DotNet.invokeMethod
: Synchroniczne tylko dla składników po stronie klienta.
Przekaż nazwę zestawu zawierającego metodę, identyfikator statycznej metody .NET i wszelkie argumenty.
W poniższym przykładzie:
- Symbol
{ASSEMBLY NAME}
zastępczy to nazwa zestawu aplikacji. - Symbol
{.NET METHOD ID}
zastępczy jest identyfikatorem metody .NET. - Symbol
{ARGUMENTS}
zastępczy to opcjonalne argumenty rozdzielane przecinkami, które mają zostać przekazane do metody, z których każda musi być serializowana w formacie JSON.
DotNet.invokeMethodAsync('{ASSEMBLY NAME}', '{.NET METHOD ID}', {ARGUMENTS});
DotNet.invokeMethodAsync
JS Promise
zwraca wynik operacji. DotNet.invokeMethod
(składniki po stronie klienta) zwraca wynik operacji.
Ważne
W przypadku składników po stronie serwera zalecamy funkcję asynchroniczną (invokeMethodAsync
) w wersji synchronicznej (invokeMethod
).
Metoda .NET musi być publiczna, statyczna i mieć [JSInvokable]
atrybut .
W poniższym przykładzie:
- Symbol
{<T>}
zastępczy wskazuje typ zwracany, który jest wymagany tylko dla metod, które zwracają wartość. - Symbol
{.NET METHOD ID}
zastępczy jest identyfikatorem metody.
@code {
[JSInvokable]
public static Task{<T>} {.NET METHOD ID}()
{
...
}
}
Uwaga
Wywoływanie otwartych metod ogólnych nie jest obsługiwane przy użyciu statycznych metod platformy .NET, ale jest obsługiwane za pomocą metod wystąpienia. Aby uzyskać więcej informacji, zobacz sekcję Wywoływanie metod klasy ogólnej platformy .NET.
W poniższym składniku ReturnArrayAsync
metoda języka C# zwraca tablicę int
. Atrybut [JSInvokable]
jest stosowany do metody , co sprawia, że metoda jest wywoływana przez JS.
CallDotnet1.razor
:
@page "/call-dotnet-1"
@implements IAsyncDisposable
@inject IJSRuntime JS
<PageTitle>Call .NET 1</PageTitle>
<h1>Call .NET Example 1</h1>
<p>
<button id="btn">Trigger .NET static method</button>
</p>
<p>
See the result in the developer tools console.
</p>
@code {
private IJSObjectReference? module;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Components/Pages/CallDotnet1.razor.js");
await module.InvokeVoidAsync("addHandlers");
}
}
[JSInvokable]
public static Task<int[]> ReturnArrayAsync() =>
Task.FromResult(new int[] { 11, 12, 13 });
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
}
CallDotnet1.razor.js
:
export function returnArrayAsync() {
DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync')
.then(data => {
console.log(data);
});
}
export function addHandlers() {
const btn = document.getElementById("btn");
btn.addEventListener("click", returnArrayAsync);
}
Funkcja addHandlers
JS dodaje click
zdarzenie do przycisku. Funkcja returnArrayAsync
JS jest przypisywana jako procedura obsługi.
Funkcja returnArrayAsync
JS wywołuje metodę ReturnArrayAsync
.NET składnika, która rejestruje wynik w konsoli narzędzi deweloperskich przeglądarki. BlazorSample
to nazwa zestawu aplikacji.
CallDotnet1.razor
:
@page "/call-dotnet-1"
@implements IAsyncDisposable
@inject IJSRuntime JS
<PageTitle>Call .NET 1</PageTitle>
<h1>Call .NET Example 1</h1>
<p>
<button id="btn">Trigger .NET static method</button>
</p>
<p>
See the result in the developer tools console.
</p>
@code {
private IJSObjectReference? module;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Components/Pages/CallDotnet1.razor.js");
await module.InvokeVoidAsync("addHandlers");
}
}
[JSInvokable]
public static Task<int[]> ReturnArrayAsync() =>
Task.FromResult(new int[] { 11, 12, 13 });
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
}
CallDotnet1.razor.js
:
export function returnArrayAsync() {
DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync')
.then(data => {
console.log(data);
});
}
export function addHandlers() {
const btn = document.getElementById("btn");
btn.addEventListener("click", returnArrayAsync);
}
Funkcja addHandlers
JS dodaje click
zdarzenie do przycisku. Funkcja returnArrayAsync
JS jest przypisywana jako procedura obsługi.
Funkcja returnArrayAsync
JS wywołuje metodę ReturnArrayAsync
.NET składnika, która rejestruje wynik w konsoli narzędzi deweloperskich przeglądarki. BlazorSample
to nazwa zestawu aplikacji.
CallDotNetExample1.razor
:
@page "/call-dotnet-example-1"
<h1>Call .NET Example 1</h1>
<p>
<button onclick="returnArrayAsync()">
Trigger .NET static method
</button>
</p>
@code {
[JSInvokable]
public static Task<int[]> ReturnArrayAsync()
{
return Task.FromResult(new int[] { 1, 2, 3 });
}
}
CallDotNetExample1.razor
:
@page "/call-dotnet-example-1"
<h1>Call .NET Example 1</h1>
<p>
<button onclick="returnArrayAsync()">
Trigger .NET static method
</button>
</p>
@code {
[JSInvokable]
public static Task<int[]> ReturnArrayAsync()
{
return Task.FromResult(new int[] { 1, 2, 3 });
}
}
CallDotNetExample1.razor
:
@page "/call-dotnet-example-1"
<h1>Call .NET Example 1</h1>
<p>
<button onclick="returnArrayAsync()">
Trigger .NET static method
</button>
</p>
@code {
[JSInvokable]
public static Task<int[]> ReturnArrayAsync()
{
return Task.FromResult(new int[] { 1, 2, 3 });
}
}
CallDotNetExample1.razor
:
@page "/call-dotnet-example-1"
<h1>Call .NET Example 1</h1>
<p>
<button onclick="returnArrayAsync()">
Trigger .NET static method
</button>
</p>
@code {
[JSInvokable]
public static Task<int[]> ReturnArrayAsync()
{
return Task.FromResult(new int[] { 1, 2, 3 });
}
}
Atrybut <button>
HTML elementu onclick
to przypisanie procedury obsługi zdarzeń języka JavaScript onclick
do przetwarzania click
@onclick
zdarzeń, a nie Blazoratrybut dyrektywy. Funkcja returnArrayAsync
JS jest przypisywana jako procedura obsługi.
Poniższa returnArrayAsync
JS funkcja wywołuje metodę ReturnArrayAsync
.NET składnika, która rejestruje wynik w konsoli narzędzi deweloperskich przeglądarki internetowej. BlazorSample
to nazwa zestawu aplikacji.
<script>
window.returnArrayAsync = () => {
DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync')
.then(data => {
console.log(data);
});
};
</script>
Uwaga
Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Lokalizacja języka JavaScript w aplikacjach ASP.NET CoreBlazor.
Po wybraniu Trigger .NET static method
przycisku dane wyjściowe konsoli narzędzi deweloperskich przeglądarki wyświetlają dane tablicy. Format danych wyjściowych różni się nieco między przeglądarkami. Następujące dane wyjściowe pokazują format używany przez przeglądarkę Microsoft Edge:
Array(3) [ 11, 12, 13 ]
Przekazywanie danych do metody .NET podczas wywoływania invokeMethodAsync
funkcji przez przekazanie danych jako argumentów.
Aby zademonstrować przekazywanie danych do platformy .NET, przekaż pozycję początkową do ReturnArrayAsync
metody, w której metoda jest wywoływana w pliku JS:
export function returnArrayAsync() {
DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync', 14)
.then(data => {
console.log(data);
});
}
<script>
window.returnArrayAsync = () => {
DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync', 14)
.then(data => {
console.log(data);
});
};
</script>
Wywołana ReturnArrayAsync
metoda składnika odbiera pozycję początkową i konstruuje tablicę z niej. Tablica jest zwracana do rejestrowania w konsoli:
[JSInvokable]
public static Task<int[]> ReturnArrayAsync(int startPosition) =>
Task.FromResult(Enumerable.Range(startPosition, 3).ToArray());
Po ponownym skompilowanej aplikacji i odświeżeniu przeglądarki w konsoli przeglądarki zostaną wyświetlone następujące dane wyjściowe po wybraniu przycisku:
Array(3) [ 14, 15, 16 ]
Identyfikator metody platformy .NET dla wywołania JS to nazwa metody .NET, ale można określić inny identyfikator przy użyciu konstruktora atrybutu[JSInvokable]
. W poniższym przykładzie DifferentMethodName
jest przypisanym identyfikatorem ReturnArrayAsync
metody dla metody :
[JSInvokable("DifferentMethodName")]
W wywołaniu metody DotNet.invokeMethodAsync
(składniki po stronie serwera lub po stronie klienta) lub DotNet.invokeMethod
(tylko składniki po stronie klienta) wywołaj metodę ReturnArrayAsync
DifferentMethodName
.NET:
DotNet.invokeMethodAsync('BlazorSample', 'DifferentMethodName');
DotNet.invokeMethod('BlazorSample', 'DifferentMethodName');
(tylko składniki po stronie klienta)
Uwaga
Przykład ReturnArrayAsync
metody w tej sekcji zwraca wynik Task bez użycia jawnego języka C# async
i await
słów kluczowych. Metody kodowania za pomocą async
metod i await
są typowe dla metod, które używają await
słowa kluczowego do zwracania wartości operacji asynchronicznych.
ReturnArrayAsync
metoda skomponowana z słowami kluczowymi async
i await
:
[JSInvokable]
public static async Task<int[]> ReturnArrayAsync() =>
await Task.FromResult(new int[] { 11, 12, 13 });
Aby uzyskać więcej informacji, zobacz Asynchroniczne programowanie za pomocą asynchronicznego i await w przewodniku języka C#.
Tworzenie odwołań do obiektów i danych języka JavaScript w celu przekazania do platformy .NET
Wywołaj metodę JS DotNet.createJSObjectReference(jsObject)
konstruowania odwołania do obiektu, aby można było przekazać go do platformy .NET, gdzie jsObject
jest JS Object
używany do tworzenia JS odwołania do obiektu. Poniższy przykład przekazuje odwołanie do obiektu nies serializowalnego window
na platformie .NET, który odbiera go w ReceiveWindowObject
metodzie języka C# jako element IJSObjectReference:
DotNet.invokeMethodAsync('{ASSEMBLY NAME}', 'ReceiveWindowObject',
DotNet.createJSObjectReference(window));
[JSInvokable]
public static void ReceiveWindowObject(IJSObjectReference objRef)
{
...
}
W poprzednim przykładzie {ASSEMBLY NAME}
symbol zastępczy to przestrzeń nazw aplikacji.
Uwaga
Powyższy przykład nie wymaga usunięcia JSObjectReference
obiektu , ponieważ odwołanie do window
obiektu nie jest przechowywane w obiekcie JS.
Utrzymywanie odwołania do elementu JSObjectReference
wymaga jego zdysponowania, aby uniknąć wycieku JS pamięci na kliencie. Poniższy przykład refaktoryzuje powyższy kod, aby przechwycić odwołanie do JSObjectReference
elementu , a następnie wywołanie metody w celu DotNet.disposeJSObjectReference()
usunięcia odwołania:
var jsObjectReference = DotNet.createJSObjectReference(window);
DotNet.invokeMethodAsync('{ASSEMBLY NAME}', 'ReceiveWindowObject', jsObjectReference);
DotNet.disposeJSObjectReference(jsObjectReference);
W poprzednim przykładzie {ASSEMBLY NAME}
symbol zastępczy to przestrzeń nazw aplikacji.
Wywołaj metodę DotNet.createJSStreamReference(streamReference)
konstruowania odwołania do strumieniaJS, aby można było przekazać ją do platformy .NET, gdzie streamReference
jest tablicą typu , Blob
lub dowolną ArrayBuffer
tablicą typową, taką jak Uint8Array
lub Float32Array
, użytą do utworzenia odwołania do strumieniaJS.
Wywoływanie metody wystąpienia platformy .NET
Aby wywołać metodę wystąpienia platformy .NET z poziomu języka JavaScript (JS):
Przekaż wystąpienie platformy .NET, odwołując się do JS niego, opakowując wystąpienie w obiekcie DotNetObjectReference i wywołując Create je.
Wywołaj metodę wystąpienia platformy .NET przy JS użyciu metody
invokeMethodAsync
(zalecane) lubinvokeMethod
(tylko składniki po stronie klienta) z przekazanego DotNetObjectReferenceelementu . Przekaż identyfikator metody .NET wystąpienia i wszystkie argumenty. Wystąpienie platformy .NET można również przekazać jako argument podczas wywoływania innych metod platformy .NET z programu JS.W poniższym przykładzie:
dotNetHelper
jest .DotNetObjectReference- Symbol
{.NET METHOD ID}
zastępczy jest identyfikatorem metody .NET. - Symbol
{ARGUMENTS}
zastępczy to opcjonalne argumenty rozdzielane przecinkami, które mają zostać przekazane do metody, z których każda musi być serializowana w formacie JSON.
dotNetHelper.invokeMethodAsync('{.NET METHOD ID}', {ARGUMENTS});
Uwaga
invokeMethodAsync
iinvokeMethod
nie akceptuj parametru nazwy zestawu podczas wywoływania metody wystąpienia.invokeMethodAsync
JSPromise
zwraca wynik operacji.invokeMethod
(tylko składniki po stronie klienta) zwraca wynik operacji.Ważne
W przypadku składników po stronie serwera zalecamy funkcję asynchroniczną (
invokeMethodAsync
) w wersji synchronicznej (invokeMethod
).Usuwanie obiektu DotNetObjectReference.
W poniższych sekcjach tego artykułu przedstawiono różne podejścia do wywoływania metody wystąpienia platformy .NET:
- Przekazywanie elementu
DotNetObjectReference
do pojedynczej funkcji Języka JavaScript - Przekazywanie klasy
DotNetObjectReference
do klasy z wieloma funkcjami Języka JavaScript - Wywoływanie metod klasy ogólnej platformy .NET
- Przykłady wystąpień klas
- Klasa pomocnika metody wystąpienia składnika platformy .NET
Unikaj przycinania metod javaScript-invokable .NET
Ta sekcja dotyczy aplikacji po stronie klienta z włączoną kompilacją przed czasem (AOT) i ponownym łączeniem środowiska uruchomieniowego.
Kilka przykładów w poniższych sekcjach jest opartych na podejściu wystąpienia klasy, w którym metoda javaScript-invokable .NET oznaczona atrybutem [JSInvokable]
jest składową klasy, która nie jest składnikiemRazor. Gdy takie metody platformy .NET znajdują się w składniku Razor , są chronione przed ponownym łączeniem/przycinaniem środowiska uruchomieniowego. Aby chronić metody .NET przed przycinaniem poza składnikamiRazor, zaimplementuj metody z atrybutem DynamicDependency
w konstruktorze klasy, jak pokazano w poniższym przykładzie:
using System.Diagnostics.CodeAnalysis;
using Microsoft.JSInterop;
public class ExampleClass {
[DynamicDependency(nameof(ExampleJSInvokableMethod))]
public ExampleClass()
{
}
[JSInvokable]
public string ExampleJSInvokableMethod()
{
...
}
}
Aby uzyskać więcej informacji, zobacz Przygotowywanie bibliotek .NET do przycinania: DynamicDependency.
Przekazywanie elementu DotNetObjectReference
do pojedynczej funkcji Języka JavaScript
W przykładzie w tej sekcji pokazano, jak przekazać element DotNetObjectReference do pojedynczej funkcji Języka JavaScript (JS).
Następująca sayHello1
JS funkcja odbiera DotNetObjectReference wywołania invokeMethodAsync
metody i w celu wywołania GetHelloMessage
metody .NET składnika:
<script>
window.sayHello1 = (dotNetHelper) => {
return dotNetHelper.invokeMethodAsync('GetHelloMessage');
};
</script>
Uwaga
Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Lokalizacja języka JavaScript w aplikacjach ASP.NET CoreBlazor.
W poprzednim przykładzie nazwa dotNetHelper
zmiennej jest dowolna i można ją zmienić na dowolną preferowaną nazwę.
Dla następującego składnika:
- Składnik ma metodę JS-invokable .NET o nazwie
GetHelloMessage
. - Po wybraniu
Trigger .NET instance method
JS przycisku funkcja jest wywoływana za pomocą .sayHello1
DotNetObjectReference sayHello1
:- Wywołuje
GetHelloMessage
i odbiera wynik komunikatu. - Zwraca wynik komunikatu do metody wywołującej
TriggerDotNetInstanceMethod
.
- Wywołuje
- Zwrócony komunikat z
sayHello1
inresult
jest wyświetlany użytkownikowi. - Aby uniknąć przecieku pamięci i umożliwić odzyskiwanie pamięci, odwołanie do obiektu platformy .NET utworzonego przez DotNetObjectReference program jest usuwane w metodzie
Dispose
.
CallDotnet2.razor
:
@page "/call-dotnet-2"
@implements IDisposable
@inject IJSRuntime JS
<PageTitle>Call .NET 2</PageTitle>
<h1>Call .NET Example 2</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private DotNetObjectReference<CallDotnet2>? objRef;
protected override void OnInitialized() =>
objRef = DotNetObjectReference.Create(this);
public async Task TriggerDotNetInstanceMethod() =>
result = await JS.InvokeAsync<string>("sayHello1", objRef);
[JSInvokable]
public string GetHelloMessage() => $"Hello, {name}!";
public void Dispose() => objRef?.Dispose();
}
CallDotnet2.razor
:
@page "/call-dotnet-2"
@implements IDisposable
@inject IJSRuntime JS
<PageTitle>Call .NET 2</PageTitle>
<h1>Call .NET Example 2</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private DotNetObjectReference<CallDotnet2>? objRef;
protected override void OnInitialized() =>
objRef = DotNetObjectReference.Create(this);
public async Task TriggerDotNetInstanceMethod() =>
result = await JS.InvokeAsync<string>("sayHello1", objRef);
[JSInvokable]
public string GetHelloMessage() => $"Hello, {name}!";
public void Dispose() => objRef?.Dispose();
}
CallDotNetExample2.razor
:
@page "/call-dotnet-example-2"
@implements IDisposable
@inject IJSRuntime JS
<h1>Call .NET Example 2</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private DotNetObjectReference<CallDotNetExample2>? objRef;
protected override void OnInitialized()
{
objRef = DotNetObjectReference.Create(this);
}
public async Task TriggerDotNetInstanceMethod()
{
result = await JS.InvokeAsync<string>("sayHello1", objRef);
}
[JSInvokable]
public string GetHelloMessage() => $"Hello, {name}!";
public void Dispose()
{
objRef?.Dispose();
}
}
CallDotNetExample2.razor
:
@page "/call-dotnet-example-2"
@implements IDisposable
@inject IJSRuntime JS
<h1>Call .NET Example 2</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private DotNetObjectReference<CallDotNetExample2>? objRef;
protected override void OnInitialized()
{
objRef = DotNetObjectReference.Create(this);
}
public async Task TriggerDotNetInstanceMethod()
{
result = await JS.InvokeAsync<string>("sayHello1", objRef);
}
[JSInvokable]
public string GetHelloMessage() => $"Hello, {name}!";
public void Dispose()
{
objRef?.Dispose();
}
}
CallDotNetExample2.razor
:
@page "/call-dotnet-example-2"
@implements IDisposable
@inject IJSRuntime JS
<h1>Call .NET Example 2</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string name;
private string result;
private DotNetObjectReference<CallDotNetExample2> objRef;
protected override void OnInitialized()
{
objRef = DotNetObjectReference.Create(this);
}
public async Task TriggerDotNetInstanceMethod()
{
result = await JS.InvokeAsync<string>("sayHello1", objRef);
}
[JSInvokable]
public string GetHelloMessage() => $"Hello, {name}!";
public void Dispose()
{
objRef?.Dispose();
}
}
CallDotNetExample2.razor
:
@page "/call-dotnet-example-2"
@implements IDisposable
@inject IJSRuntime JS
<h1>Call .NET Example 2</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string name;
private string result;
private DotNetObjectReference<CallDotNetExample2> objRef;
protected override void OnInitialized()
{
objRef = DotNetObjectReference.Create(this);
}
public async Task TriggerDotNetInstanceMethod()
{
result = await JS.InvokeAsync<string>("sayHello1", objRef);
}
[JSInvokable]
public string GetHelloMessage() => $"Hello, {name}!";
public void Dispose()
{
objRef?.Dispose();
}
}
W poprzednim przykładzie nazwa dotNetHelper
zmiennej jest dowolna i można ją zmienić na dowolną preferowaną nazwę.
Skorzystaj z poniższych wskazówek, aby przekazać argumenty do metody wystąpienia:
Dodaj parametry do wywołania metody .NET. W poniższym przykładzie nazwa jest przekazywana do metody . Dodaj dodatkowe parametry do listy zgodnie z potrzebami.
<script>
window.sayHello2 = (dotNetHelper, name) => {
return dotNetHelper.invokeMethodAsync('GetHelloMessage', name);
};
</script>
W poprzednim przykładzie nazwa dotNetHelper
zmiennej jest dowolna i można ją zmienić na dowolną preferowaną nazwę.
Podaj listę parametrów do metody .NET.
CallDotnet3.razor
:
@page "/call-dotnet-3"
@implements IDisposable
@inject IJSRuntime JS
<PageTitle>Call .NET 3</PageTitle>
<h1>Call .NET Example 3</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private DotNetObjectReference<CallDotnet3>? objRef;
protected override void OnInitialized() =>
objRef = DotNetObjectReference.Create(this);
public async Task TriggerDotNetInstanceMethod() =>
result = await JS.InvokeAsync<string>("sayHello2", objRef, name);
[JSInvokable]
public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";
public void Dispose() => objRef?.Dispose();
}
CallDotnet3.razor
:
@page "/call-dotnet-3"
@implements IDisposable
@inject IJSRuntime JS
<PageTitle>Call .NET 3</PageTitle>
<h1>Call .NET Example 3</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private DotNetObjectReference<CallDotnet3>? objRef;
protected override void OnInitialized() =>
objRef = DotNetObjectReference.Create(this);
public async Task TriggerDotNetInstanceMethod() =>
result = await JS.InvokeAsync<string>("sayHello2", objRef, name);
[JSInvokable]
public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";
public void Dispose() => objRef?.Dispose();
}
CallDotNetExample3.razor
:
@page "/call-dotnet-example-3"
@implements IDisposable
@inject IJSRuntime JS
<h1>Call .NET Example 3</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private DotNetObjectReference<CallDotNetExample3>? objRef;
protected override void OnInitialized()
{
objRef = DotNetObjectReference.Create(this);
}
public async Task TriggerDotNetInstanceMethod()
{
result = await JS.InvokeAsync<string>("sayHello2", objRef, name);
}
[JSInvokable]
public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";
public void Dispose()
{
objRef?.Dispose();
}
}
CallDotNetExample3.razor
:
@page "/call-dotnet-example-3"
@implements IDisposable
@inject IJSRuntime JS
<h1>Call .NET Example 3</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private DotNetObjectReference<CallDotNetExample3>? objRef;
protected override void OnInitialized()
{
objRef = DotNetObjectReference.Create(this);
}
public async Task TriggerDotNetInstanceMethod()
{
result = await JS.InvokeAsync<string>("sayHello2", objRef, name);
}
[JSInvokable]
public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";
public void Dispose()
{
objRef?.Dispose();
}
}
CallDotNetExample3.razor
:
@page "/call-dotnet-example-3"
@implements IDisposable
@inject IJSRuntime JS
<h1>Call .NET Example 3</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string name;
private string result;
private DotNetObjectReference<CallDotNetExample3> objRef;
protected override void OnInitialized()
{
objRef = DotNetObjectReference.Create(this);
}
public async Task TriggerDotNetInstanceMethod()
{
result = await JS.InvokeAsync<string>("sayHello2", objRef, name);
}
[JSInvokable]
public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";
public void Dispose()
{
objRef?.Dispose();
}
}
CallDotNetExample3.razor
:
@page "/call-dotnet-example-3"
@implements IDisposable
@inject IJSRuntime JS
<h1>Call .NET Example 3</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string name;
private string result;
private DotNetObjectReference<CallDotNetExample3> objRef;
protected override void OnInitialized()
{
objRef = DotNetObjectReference.Create(this);
}
public async Task TriggerDotNetInstanceMethod()
{
result = await JS.InvokeAsync<string>("sayHello2", objRef, name);
}
[JSInvokable]
public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";
public void Dispose()
{
objRef?.Dispose();
}
}
W poprzednim przykładzie nazwa dotNetHelper
zmiennej jest dowolna i można ją zmienić na dowolną preferowaną nazwę.
Przekazywanie klasy DotNetObjectReference
do klasy z wieloma funkcjami Języka JavaScript
W przykładzie w tej sekcji pokazano, jak przekazać element DotNetObjectReference do klasy JavaScript (JS) z wieloma funkcjami.
Utwórz i przekaż element DotNetObjectReference z OnAfterRenderAsync
metody cyklu życia do JS klasy dla wielu funkcji do użycia. Upewnij się, że kod platformy .NET usuwa DotNetObjectReferenceelement , jak pokazano w poniższym przykładzie.
W poniższym składniku przyciski wywołuje funkcje, Trigger JS function
ustawiając JSonclick
właściwość, a nie Blazor@onclick
atrybut dyrektywy.JS
CallDotNetExampleOneHelper.razor
:
@page "/call-dotnet-example-one-helper"
@implements IAsyncDisposable
@inject IJSRuntime JS
<PageTitle>Call .NET Example</PageTitle>
<h1>Pass <code>DotNetObjectReference</code> to a JavaScript class</h1>
<p>
<label>
Message: <input @bind="name" />
</label>
</p>
<p>
<button id="sayHelloBtn">
Trigger JS function <code>sayHello</code>
</button>
</p>
<p>
<button id="welcomeVisitorBtn">
Trigger JS function <code>welcomeVisitor</code>
</button>
</p>
@code {
private IJSObjectReference? module;
private string? name;
private DotNetObjectReference<CallDotNetExampleOneHelper>? dotNetHelper;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Components/Pages/CallDotNetExampleOneHelper.razor.js");
dotNetHelper = DotNetObjectReference.Create(this);
await module.InvokeVoidAsync("GreetingHelpers.setDotNetHelper",
dotNetHelper);
await module.InvokeVoidAsync("addHandlers");
}
}
[JSInvokable]
public string GetHelloMessage() => $"Hello, {name}!";
[JSInvokable]
public string GetWelcomeMessage() => $"Welcome, {name}!";
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
dotNetHelper?.Dispose();
}
}
W powyższym przykładzie:
JS
jest wystąpieniem wstrzykniętym IJSRuntime . IJSRuntime program jest zarejestrowany przez platformę Blazor .- Nazwa
dotNetHelper
zmiennej jest dowolna i może zostać zmieniona na dowolną preferowaną nazwę. - Składnik musi jawnie usunąć element, DotNetObjectReference aby umożliwić odzyskiwanie pamięci i zapobiec wyciekowi pamięci.
- JSDisconnectedException jest uwięziony podczas usuwania modułu w przypadku Blazorutraty obwodu SignalR . Jeśli poprzedni kod jest używany w Blazor WebAssembly aplikacji, nie ma SignalR połączenia do utraty, więc możesz usunąć
catch
try
-blok i pozostawić wiersz, który usuwa moduł ().await module.DisposeAsync();
Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor JavaScript interoperability (JS interop).
CallDotNetExampleOneHelper.razor.js
:
export class GreetingHelpers {
static dotNetHelper;
static setDotNetHelper(value) {
GreetingHelpers.dotNetHelper = value;
}
static async sayHello() {
const msg =
await GreetingHelpers.dotNetHelper.invokeMethodAsync('GetHelloMessage');
alert(`Message from .NET: "${msg}"`);
}
static async welcomeVisitor() {
const msg =
await GreetingHelpers.dotNetHelper.invokeMethodAsync('GetWelcomeMessage');
alert(`Message from .NET: "${msg}"`);
}
}
export function addHandlers() {
const sayHelloBtn = document.getElementById("sayHelloBtn");
sayHelloBtn.addEventListener("click", GreetingHelpers.sayHello);
const welcomeVisitorBtn = document.getElementById("welcomeVisitorBtn");
welcomeVisitorBtn.addEventListener("click", GreetingHelpers.welcomeVisitor);
}
W poprzednim przykładzie nazwa dotNetHelper
zmiennej jest dowolna i można ją zmienić na dowolną preferowaną nazwę.
@page "/call-dotnet-example-one-helper"
@implements IDisposable
@inject IJSRuntime JS
<h1>Pass <code>DotNetObjectReference</code> to a JavaScript class</h1>
<p>
<label>
Message: <input @bind="name" />
</label>
</p>
<p>
<button onclick="GreetingHelpers.sayHello()">
Trigger JS function <code>sayHello</code>
</button>
</p>
<p>
<button onclick="GreetingHelpers.welcomeVisitor()">
Trigger JS function <code>welcomeVisitor</code>
</button>
</p>
@code {
private string? name;
private DotNetObjectReference<CallDotNetExampleOneHelper>? dotNetHelper;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
dotNetHelper = DotNetObjectReference.Create(this);
await JS.InvokeVoidAsync("GreetingHelpers.setDotNetHelper",
dotNetHelper);
}
}
[JSInvokable]
public string GetHelloMessage() => $"Hello, {name}!";
[JSInvokable]
public string GetWelcomeMessage() => $"Welcome, {name}!";
public void Dispose()
{
dotNetHelper?.Dispose();
}
}
W powyższym przykładzie:
JS
jest wystąpieniem wstrzykniętym IJSRuntime . IJSRuntime program jest zarejestrowany przez platformę Blazor .- Nazwa
dotNetHelper
zmiennej jest dowolna i może zostać zmieniona na dowolną preferowaną nazwę. - Składnik musi jawnie usunąć element, DotNetObjectReference aby umożliwić odzyskiwanie pamięci i zapobiec wyciekowi pamięci.
<script>
class GreetingHelpers {
static dotNetHelper;
static setDotNetHelper(value) {
GreetingHelpers.dotNetHelper = value;
}
static async sayHello() {
const msg =
await GreetingHelpers.dotNetHelper.invokeMethodAsync('GetHelloMessage');
alert(`Message from .NET: "${msg}"`);
}
static async welcomeVisitor() {
const msg =
await GreetingHelpers.dotNetHelper.invokeMethodAsync('GetWelcomeMessage');
alert(`Message from .NET: "${msg}"`);
}
}
window.GreetingHelpers = GreetingHelpers;
</script>
W powyższym przykładzie:
- Klasa
GreetingHelpers
jest dodawana dowindow
obiektu w celu globalnego zdefiniowania klasy, która umożliwia Blazor zlokalizowanie klasy dla JS międzyoperacyjności. - Nazwa
dotNetHelper
zmiennej jest dowolna i może zostać zmieniona na dowolną preferowaną nazwę.
Uwaga
Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Lokalizacja języka JavaScript w aplikacjach ASP.NET CoreBlazor.
Wywoływanie metod klasy ogólnej platformy .NET
Funkcje języka JavaScript (JS) mogą wywoływać metody klasy ogólnej platformy .NET, gdzie JS funkcja wywołuje metodę .NET klasy ogólnej.
W następującej klasie typu ogólnego (GenericType<TValue>
):
- Klasa ma pojedynczy parametr typu (
TValue
) z jedną właściwością ogólnąValue
. - Klasa ma dwie metody inne niż ogólne oznaczone atrybutem
[JSInvokable]
, z których każdy ma parametr typu ogólnego o nazwienewValue
:Update
synchronicznie aktualizuje wartośćValue
znewValue
.UpdateAsync
asynchronicznie aktualizuje wartośćValue
znewValue
po utworzeniu oczekiwanego zadania, Task.Yield gdy asynchronicznie zwraca bieżący kontekst w oczekiwanym czasie.
- Każda z metod klasy zapisuje typ
TValue
i wartośćValue
w konsoli. Zapisywanie w konsoli jest przeznaczone tylko do celów demonstracyjnych. Aplikacje produkcyjne zwykle unikają zapisywania w konsoli na rzecz rejestrowania aplikacji. Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor logging and Logging in .NET Core and ASP.NET Core (Rejestrowanie i rejestrowanie na platformie .NET Core) i ASP.NET Core.
Uwaga
Otwarte typy ogólne i metody nie określają typów dla symboli zastępczych typów. Z drugiej strony zamknięte typy dostaw typów ogólnych dla wszystkich symboli zastępczych typów. Przykłady w tej sekcji przedstawiają zamknięte typy ogólne, ale wywoływanie metod wystąpienia międzyoperacyjnego z otwartymi rodzajami ogólnymi jest obsługiwane. JS Używanie otwartych typów ogólnych nie jest obsługiwane w przypadku wywołań statycznych metod platformy .NET, które zostały opisane wcześniej w tym artykule.
Aby uzyskać więcej informacji, zobacz następujące artykuły:
- Klasy ogólne i metody (dokumentacja języka C#)
- Klasy ogólne (Przewodnik programowania w języku C#)
- Typy ogólne na platformie .NET (dokumentacja platformy .NET)
GenericType.cs
:
using Microsoft.JSInterop;
public class GenericType<TValue>
{
public TValue? Value { get; set; }
[JSInvokable]
public void Update(TValue newValue)
{
Value = newValue;
Console.WriteLine($"Update: GenericType<{typeof(TValue)}>: {Value}");
}
[JSInvokable]
public async void UpdateAsync(TValue newValue)
{
await Task.Yield();
Value = newValue;
Console.WriteLine($"UpdateAsync: GenericType<{typeof(TValue)}>: {Value}");
}
}
W następującej invokeMethodsAsync
funkcji:
- Metody i
UpdateAsync
klasyUpdate
typów ogólnych są wywoływane z argumentami reprezentującymi ciągi i liczby. - Składniki po stronie klienta obsługują synchronicznie wywoływanie metod platformy .NET za pomocą polecenia
invokeMethod
.syncInterop
otrzymuje wartość logiczną wskazującą, czy międzyoperacyjna JS występuje na kliencie. GdysyncInterop
parametr totrue
,invokeMethod
jest bezpiecznie wywoływany. Jeśli wartośćsyncInterop
tofalse
, wywoływana jest tylko funkcjainvokeMethodAsync
asynchroniczna, ponieważ JS międzyoperacyjna jest wykonywana w składniku po stronie serwera. - W celach DotNetObjectReference demonstracyjnych wywołanie funkcji (
invokeMethod
lubinvokeMethodAsync
), metoda .NET o nazwie (Update
lubUpdateAsync
) i argument są zapisywane w konsoli. Argumenty używają liczby losowej, aby zezwolić na dopasowanie JS wywołania metody .NET do wywołania metody .NET (również zapisanej w konsoli po stronie platformy .NET). Kod produkcyjny zwykle nie jest zapisywany w konsoli programu na kliencie lub serwerze. Aplikacje produkcyjne zwykle polegają na rejestrowaniu aplikacji. Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor logging and Logging in .NET Core and ASP.NET Core (Rejestrowanie i rejestrowanie na platformie .NET Core) i ASP.NET Core.
<script>
const randomInt = () => Math.floor(Math.random() * 99999);
window.invokeMethodsAsync = async (syncInterop, dotNetHelper1, dotNetHelper2) => {
var n = randomInt();
console.log(`JS: invokeMethodAsync:Update('string ${n}')`);
await dotNetHelper1.invokeMethodAsync('Update', `string ${n}`);
n = randomInt();
console.log(`JS: invokeMethodAsync:UpdateAsync('string ${n}')`);
await dotNetHelper1.invokeMethodAsync('UpdateAsync', `string ${n}`);
if (syncInterop) {
n = randomInt();
console.log(`JS: invokeMethod:Update('string ${n}')`);
dotNetHelper1.invokeMethod('Update', `string ${n}`);
}
n = randomInt();
console.log(`JS: invokeMethodAsync:Update(${n})`);
await dotNetHelper2.invokeMethodAsync('Update', n);
n = randomInt();
console.log(`JS: invokeMethodAsync:UpdateAsync(${n})`);
await dotNetHelper2.invokeMethodAsync('UpdateAsync', n);
if (syncInterop) {
n = randomInt();
console.log(`JS: invokeMethod:Update(${n})`);
dotNetHelper2.invokeMethod('Update', n);
}
};
</script>
Uwaga
Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Lokalizacja języka JavaScript w aplikacjach ASP.NET CoreBlazor.
W poniższym składniku GenericsExample
:
invokeMethodsAsync
Funkcja jest wywoływana JS po wybraniuInvoke Interop
przycisku.- Para DotNetObjectReference typów jest tworzona i przekazywana do JS funkcji dla wystąpień
GenericType
klasy jako istring
int
.
GenericsExample.razor
:
@page "/generics-example"
@implements IDisposable
@inject IJSRuntime JS
<p>
<button @onclick="InvokeInterop">Invoke Interop</button>
</p>
<ul>
<li>genericType1: @genericType1?.Value</li>
<li>genericType2: @genericType2?.Value</li>
</ul>
@code {
private GenericType<string> genericType1 = new() { Value = "string 0" };
private GenericType<int> genericType2 = new() { Value = 0 };
private DotNetObjectReference<GenericType<string>>? objRef1;
private DotNetObjectReference<GenericType<int>>? objRef2;
protected override void OnInitialized()
{
objRef1 = DotNetObjectReference.Create(genericType1);
objRef2 = DotNetObjectReference.Create(genericType2);
}
public async Task InvokeInterop()
{
var syncInterop = OperatingSystem.IsBrowser();
await JS.InvokeVoidAsync(
"invokeMethodsAsync", syncInterop, objRef1, objRef2);
}
public void Dispose()
{
objRef1?.Dispose();
objRef2?.Dispose();
}
}
@page "/generics-example"
@implements IDisposable
@inject IJSRuntime JS
<p>
<button @onclick="InvokeInterop">Invoke Interop</button>
</p>
<ul>
<li>genericType1: @genericType1?.Value</li>
<li>genericType2: @genericType2?.Value</li>
</ul>
@code {
private GenericType<string> genericType1 = new() { Value = "string 0" };
private GenericType<int> genericType2 = new() { Value = 0 };
private DotNetObjectReference<GenericType<string>>? objRef1;
private DotNetObjectReference<GenericType<int>>? objRef2;
protected override void OnInitialized()
{
objRef1 = DotNetObjectReference.Create(genericType1);
objRef2 = DotNetObjectReference.Create(genericType2);
}
public async Task InvokeInterop()
{
var syncInterop = OperatingSystem.IsBrowser();
await JS.InvokeVoidAsync(
"invokeMethodsAsync", syncInterop, objRef1, objRef2);
}
public void Dispose()
{
objRef1?.Dispose();
objRef2?.Dispose();
}
}
W poprzednim przykładzie JS
jest wstrzyknięte IJSRuntime wystąpienie. IJSRuntime program jest zarejestrowany przez platformę Blazor .
Poniżej przedstawiono typowe dane wyjściowe z poprzedniego przykładu, gdy Invoke Interop
przycisk jest wybrany w składniku po stronie klienta:
JS: invokeMethodAsync:Update('string 37802')
.NET: Update: GenericType<System.String>: ciąg 37802
JS: invokeMethodAsync:UpdateAsync('string 53051')
JS: invokeMethod:Update('string 26784')
.NET: Update: GenericType<System.String>: ciąg 26784
JS: invokeMethodAsync:Update(14107)
.NET: Aktualizacja: GenericType<System.Int32>: 14107
JS: invokeMethodAsync:UpdateAsync(48995)
JS: invokeMethod:Update(12872)
.NET: Aktualizacja: GenericType<System.Int32>: 12872
.NET: UpdateAsync: GenericType<System.String>: ciąg 53051
.NET: UpdateAsync: GenericType<System.Int32>: 48995
Jeśli powyższy przykład jest implementowany w składniku po stronie serwera, unika się wywołań synchronicznych.invokeMethod
W przypadku składników po stronie serwera zalecamy funkcję asynchroniczną (invokeMethodAsync
) w wersji synchronicznej (invokeMethod
).
Typowe dane wyjściowe składnika po stronie serwera:
JS: invokeMethodAsync:Update('string 34809')
.NET: Update: GenericType<System.String>: ciąg 34809
JS: invokeMethodAsync:UpdateAsync('string 93059')
JS: invokeMethodAsync:Update(41997)
.NET: Aktualizacja: GenericType<System.Int32>: 41997
JS: invokeMethodAsync:UpdateAsync(24652)
.NET: UpdateAsync: GenericType<System.String>: ciąg 93059
.NET: UpdateAsync: GenericType<System.Int32>: 24652
Powyższe przykłady danych wyjściowych pokazują, że metody asynchroniczne są wykonywane i wykonywane w dowolnej kolejności w zależności od kilku czynników, w tym planowania wątków i szybkości wykonywania metody. Nie można niezawodnie przewidzieć kolejności ukończenia wywołań metody asynchronicznej.
Przykłady wystąpień klas
Następująca sayHello1
JS funkcja:
- Wywołuje metodę
GetHelloMessage
.NET w przekazanym DotNetObjectReferencepliku . - Zwraca komunikat z
GetHelloMessage
do obiektu wywołującegosayHello1
.
<script>
window.sayHello1 = (dotNetHelper) => {
return dotNetHelper.invokeMethodAsync('GetHelloMessage');
};
</script>
Uwaga
Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Lokalizacja języka JavaScript w aplikacjach ASP.NET CoreBlazor.
W poprzednim przykładzie nazwa dotNetHelper
zmiennej jest dowolna i można ją zmienić na dowolną preferowaną nazwę.
Poniższa HelloHelper
klasa ma metodę JS-invokable .NET o nazwie GetHelloMessage
. Po HelloHelper
utworzeniu Name
nazwa właściwości jest używana do zwracania komunikatu z .GetHelloMessage
HelloHelper.cs
:
using Microsoft.JSInterop;
namespace BlazorSample;
public class HelloHelper(string? name)
{
public string? Name { get; set; } = name ?? "No Name";
[JSInvokable]
public string GetHelloMessage() => $"Hello, {Name}!";
}
using Microsoft.JSInterop;
namespace BlazorSample;
public class HelloHelper(string? name)
{
public string? Name { get; set; } = name ?? "No Name";
[JSInvokable]
public string GetHelloMessage() => $"Hello, {Name}!";
}
using Microsoft.JSInterop;
public class HelloHelper
{
public HelloHelper(string? name)
{
Name = name ?? "No Name";
}
public string? Name { get; set; }
[JSInvokable]
public string GetHelloMessage() => $"Hello, {Name}!";
}
using Microsoft.JSInterop;
public class HelloHelper
{
public HelloHelper(string? name)
{
Name = name ?? "No Name";
}
public string? Name { get; set; }
[JSInvokable]
public string GetHelloMessage() => $"Hello, {Name}!";
}
using Microsoft.JSInterop;
public class HelloHelper
{
public HelloHelper(string name)
{
Name = name;
}
public string Name { get; set; }
[JSInvokable]
public string GetHelloMessage() => $"Hello, {Name}!";
}
using Microsoft.JSInterop;
public class HelloHelper
{
public HelloHelper(string name)
{
Name = name;
}
public string Name { get; set; }
[JSInvokable]
public string GetHelloMessage() => $"Hello, {Name}!";
}
Metoda CallHelloHelperGetHelloMessage
w poniższej JsInteropClasses3
klasie wywołuje JS funkcję sayHello1
z nowym wystąpieniem HelloHelper
klasy .
JsInteropClasses3.cs
:
using Microsoft.JSInterop;
namespace BlazorSample;
public class JsInteropClasses3(IJSRuntime js)
{
private readonly IJSRuntime js = js;
public async ValueTask<string> CallHelloHelperGetHelloMessage(string? name)
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
return await js.InvokeAsync<string>("sayHello1", objRef);
}
}
using Microsoft.JSInterop;
namespace BlazorSample;
public class JsInteropClasses3(IJSRuntime js)
{
private readonly IJSRuntime js = js;
public async ValueTask<string> CallHelloHelperGetHelloMessage(string? name)
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
return await js.InvokeAsync<string>("sayHello1", objRef);
}
}
using Microsoft.JSInterop;
public class JsInteropClasses3
{
private readonly IJSRuntime js;
public JsInteropClasses3(IJSRuntime js)
{
this.js = js;
}
public async ValueTask<string> CallHelloHelperGetHelloMessage(string? name)
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
return await js.InvokeAsync<string>("sayHello1", objRef);
}
}
using Microsoft.JSInterop;
public class JsInteropClasses3
{
private readonly IJSRuntime js;
public JsInteropClasses3(IJSRuntime js)
{
this.js = js;
}
public async ValueTask<string> CallHelloHelperGetHelloMessage(string? name)
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
return await js.InvokeAsync<string>("sayHello1", objRef);
}
}
using System.Threading.Tasks;
using Microsoft.JSInterop;
public class JsInteropClasses3
{
private readonly IJSRuntime js;
public JsInteropClasses3(IJSRuntime js)
{
this.js = js;
}
public async ValueTask<string> CallHelloHelperGetHelloMessage(string name)
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
return await js.InvokeAsync<string>("sayHello1", objRef);
}
}
using System.Threading.Tasks;
using Microsoft.JSInterop;
public class JsInteropClasses3
{
private readonly IJSRuntime js;
public JsInteropClasses3(IJSRuntime js)
{
this.js = js;
}
public async ValueTask<string> CallHelloHelperGetHelloMessage(string name)
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
return await js.InvokeAsync<string>("sayHello1", objRef);
}
}
Aby uniknąć przecieku pamięci i umożliwić odzyskiwanie pamięci, odwołanie do obiektu platformy .NET utworzone przez DotNetObjectReference program jest usuwane, gdy odwołanie do obiektu wykracza poza zakres ze składniąusing var
.
Trigger .NET instance method
Gdy przycisk jest zaznaczony w następującym składniku, JsInteropClasses3.CallHelloHelperGetHelloMessage
jest wywoływany z wartością name
.
CallDotnet4.razor
:
@page "/call-dotnet-4"
@inject IJSRuntime JS
<PageTitle>Call .NET 4</PageTitle>
<h1>Call .NET Example 4</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private JsInteropClasses3? jsInteropClasses;
protected override void OnInitialized() =>
jsInteropClasses = new JsInteropClasses3(JS);
private async Task TriggerDotNetInstanceMethod()
{
if (jsInteropClasses is not null)
{
result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
}
}
}
CallDotnet4.razor
:
@page "/call-dotnet-4"
@inject IJSRuntime JS
<PageTitle>Call .NET 4</PageTitle>
<h1>Call .NET Example 4</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private JsInteropClasses3? jsInteropClasses;
protected override void OnInitialized() =>
jsInteropClasses = new JsInteropClasses3(JS);
private async Task TriggerDotNetInstanceMethod()
{
if (jsInteropClasses is not null)
{
result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
}
}
}
CallDotNetExample4.razor
:
@page "/call-dotnet-example-4"
@inject IJSRuntime JS
<h1>Call .NET Example 4</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private JsInteropClasses3? jsInteropClasses;
protected override void OnInitialized()
{
jsInteropClasses = new JsInteropClasses3(JS);
}
private async Task TriggerDotNetInstanceMethod()
{
if (jsInteropClasses is not null)
{
result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
}
}
}
CallDotNetExample4.razor
:
@page "/call-dotnet-example-4"
@inject IJSRuntime JS
<h1>Call .NET Example 4</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
private JsInteropClasses3? jsInteropClasses;
protected override void OnInitialized()
{
jsInteropClasses = new JsInteropClasses3(JS);
}
private async Task TriggerDotNetInstanceMethod()
{
if (jsInteropClasses is not null)
{
result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
}
}
}
CallDotNetExample4.razor
:
@page "/call-dotnet-example-4"
@inject IJSRuntime JS
<h1>Call .NET Example 4</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string name;
private string result;
private JsInteropClasses3 jsInteropClasses;
protected override void OnInitialized()
{
jsInteropClasses = new JsInteropClasses3(JS);
}
private async Task TriggerDotNetInstanceMethod()
{
result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
}
}
CallDotNetExample4.razor
:
@page "/call-dotnet-example-4"
@inject IJSRuntime JS
<h1>Call .NET Example 4</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string name;
private string result;
private JsInteropClasses3 jsInteropClasses;
protected override void OnInitialized()
{
jsInteropClasses = new JsInteropClasses3(JS);
}
private async Task TriggerDotNetInstanceMethod()
{
result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
}
}
Na poniższej ilustracji przedstawiono renderowany składnik o nazwie Amy Pond
w Name
polu. Po wybraniu Hello, Amy Pond!
przycisku zostanie wyświetlony w interfejsie użytkownika:
Powyższy wzorzec pokazany w JsInteropClasses3
klasie można również zaimplementować całkowicie w składniku.
CallDotnet5.razor
:
@page "/call-dotnet-5"
@inject IJSRuntime JS
<PageTitle>Call .NET 5</PageTitle>
<h1>Call .NET Example 5</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
public async Task TriggerDotNetInstanceMethod()
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
result = await JS.InvokeAsync<string>("sayHello1", objRef);
}
}
CallDotnet5.razor
:
@page "/call-dotnet-5"
@inject IJSRuntime JS
<PageTitle>Call .NET 5</PageTitle>
<h1>Call .NET Example 5</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
public async Task TriggerDotNetInstanceMethod()
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
result = await JS.InvokeAsync<string>("sayHello1", objRef);
}
}
CallDotNetExample5.razor
:
@page "/call-dotnet-example-5"
@inject IJSRuntime JS
<h1>Call .NET Example 5</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
public async Task TriggerDotNetInstanceMethod()
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
result = await JS.InvokeAsync<string>("sayHello1", objRef);
}
}
CallDotNetExample5.razor
:
@page "/call-dotnet-example-5"
@inject IJSRuntime JS
<h1>Call .NET Example 5</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string? name;
private string? result;
public async Task TriggerDotNetInstanceMethod()
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
result = await JS.InvokeAsync<string>("sayHello1", objRef);
}
}
CallDotNetExample5.razor
:
@page "/call-dotnet-example-5"
@inject IJSRuntime JS
<h1>Call .NET Example 5</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string name;
private string result;
public async Task TriggerDotNetInstanceMethod()
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
result = await JS.InvokeAsync<string>("sayHello1", objRef);
}
}
CallDotNetExample5.razor
:
@page "/call-dotnet-example-5"
@inject IJSRuntime JS
<h1>Call .NET Example 5</h1>
<p>
<label>
Name: <input @bind="name" />
</label>
</p>
<p>
<button @onclick="TriggerDotNetInstanceMethod">
Trigger .NET instance method
</button>
</p>
<p>
@result
</p>
@code {
private string name;
private string result;
public async Task TriggerDotNetInstanceMethod()
{
using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
result = await JS.InvokeAsync<string>("sayHello1", objRef);
}
}
Aby uniknąć przecieku pamięci i umożliwić odzyskiwanie pamięci, odwołanie do obiektu platformy .NET utworzone przez DotNetObjectReference program jest usuwane, gdy odwołanie do obiektu wykracza poza zakres ze składniąusing var
.
Dane wyjściowe wyświetlane przez składnik są Hello, Amy Pond!
wtedy, gdy nazwa Amy Pond
jest podana name
w polu.
W poprzednim składniku odwołanie do obiektu platformy .NET jest usuwane. Jeśli klasa lub składnik nie usuwa elementu , należy go usunąć DotNetObjectReferencez klienta przez wywołanie dispose
przekazanego DotNetObjectReferenceelementu :
window.{JS FUNCTION NAME} = (dotNetHelper) => {
dotNetHelper.invokeMethodAsync('{.NET METHOD ID}');
dotNetHelper.dispose();
}
W powyższym przykładzie:
- Symbol
{JS FUNCTION NAME}
zastępczy to JS nazwa funkcji. - Nazwa
dotNetHelper
zmiennej jest dowolna i może zostać zmieniona na dowolną preferowaną nazwę. - Symbol
{.NET METHOD ID}
zastępczy jest identyfikatorem metody .NET.
Klasa pomocnika metody wystąpienia składnika platformy .NET
Klasa pomocnika może wywołać metodę wystąpienia platformy .NET jako .Action Klasy pomocnika są przydatne w scenariuszach, w których używanie statycznych metod platformy .NET nie ma zastosowania:
- Gdy na tej samej stronie jest renderowanych kilka składników tego samego typu.
- W aplikacjach po stronie serwera z wieloma użytkownikami jednocześnie używających tego samego składnika.
W poniższym przykładzie:
- Składnik zawiera kilka
ListItem1
składników. - Każdy
ListItem1
składnik składa się z komunikatu i przycisku. - Po wybraniu
ListItem1
ListItem1
przycisku składnika metoda zmieniaUpdateMessage
tekst elementu listy i ukrywa przycisk.
Poniższa MessageUpdateInvokeHelper
klasa obsługuje metodę JS.NET z możliwością wywołania metody -invokable .NET, UpdateMessageCaller
aby wywołać Action określoną klasę po utworzeniu wystąpienia klasy.
MessageUpdateInvokeHelper.cs
:
using Microsoft.JSInterop;
namespace BlazorSample;
public class MessageUpdateInvokeHelper(Action action)
{
private readonly Action action = action;
[JSInvokable]
public void UpdateMessageCaller() => action.Invoke();
}
using Microsoft.JSInterop;
namespace BlazorSample;
public class MessageUpdateInvokeHelper(Action action)
{
private readonly Action action = action;
[JSInvokable]
public void UpdateMessageCaller() => action.Invoke();
}
using Microsoft.JSInterop;
public class MessageUpdateInvokeHelper
{
private Action action;
public MessageUpdateInvokeHelper(Action action)
{
this.action = action;
}
[JSInvokable]
public void UpdateMessageCaller()
{
action.Invoke();
}
}
using Microsoft.JSInterop;
public class MessageUpdateInvokeHelper
{
private Action action;
public MessageUpdateInvokeHelper(Action action)
{
this.action = action;
}
[JSInvokable]
public void UpdateMessageCaller()
{
action.Invoke();
}
}
using System;
using Microsoft.JSInterop;
public class MessageUpdateInvokeHelper
{
private Action action;
public MessageUpdateInvokeHelper(Action action)
{
this.action = action;
}
[JSInvokable]
public void UpdateMessageCaller()
{
action.Invoke();
}
}
using System;
using Microsoft.JSInterop;
public class MessageUpdateInvokeHelper
{
private Action action;
public MessageUpdateInvokeHelper(Action action)
{
this.action = action;
}
[JSInvokable]
public void UpdateMessageCaller()
{
action.Invoke();
}
}
Poniższa updateMessageCaller
JS funkcja wywołuje metodę UpdateMessageCaller
.NET.
<script>
window.updateMessageCaller = (dotNetHelper) => {
dotNetHelper.invokeMethodAsync('UpdateMessageCaller');
dotNetHelper.dispose();
}
</script>
Uwaga
Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Lokalizacja języka JavaScript w aplikacjach ASP.NET CoreBlazor.
W poprzednim przykładzie nazwa dotNetHelper
zmiennej jest dowolna i można ją zmienić na dowolną preferowaną nazwę.
Poniższy ListItem1
składnik jest składnikiem udostępnionym, który może być używany dowolną liczbę razy w składniku nadrzędnym i tworzy elementy listy () dla listy HTML (<li>...</li>
<ul>...</ul>
lub <ol>...</ol>
). Każde ListItem1
wystąpienie składnika ustanawia wystąpienie MessageUpdateInvokeHelper
elementu z zestawem Action na jego UpdateMessage
metodę.
Po wybraniu ListItem1
InteropCall
updateMessageCaller
przycisku składnika jest wywoływany z utworzonym DotNetObjectReference wystąpieniem.MessageUpdateInvokeHelper
Dzięki temu platforma może wywołać UpdateMessageCaller
wystąpienie tego ListItem1
MessageUpdateInvokeHelper
wystąpienia. Przekazany DotNetObjectReference element jest usuwany w JS pliku (dotNetHelper.dispose()
).
ListItem1.razor
:
@inject IJSRuntime JS
<li>
@message
<button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>
@code {
private string message = "Select one of these list item buttons.";
private string display = "inline-block";
private MessageUpdateInvokeHelper? messageUpdateInvokeHelper;
protected override void OnInitialized()
{
messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
}
protected async Task InteropCall()
{
if (messageUpdateInvokeHelper is not null)
{
await JS.InvokeVoidAsync("updateMessageCaller",
DotNetObjectReference.Create(messageUpdateInvokeHelper));
}
}
private void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
StateHasChanged();
}
}
@inject IJSRuntime JS
<li>
@message
<button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>
@code {
private string message = "Select one of these list item buttons.";
private string display = "inline-block";
private MessageUpdateInvokeHelper? messageUpdateInvokeHelper;
protected override void OnInitialized()
{
messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
}
protected async Task InteropCall()
{
if (messageUpdateInvokeHelper is not null)
{
await JS.InvokeVoidAsync("updateMessageCaller",
DotNetObjectReference.Create(messageUpdateInvokeHelper));
}
}
private void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
StateHasChanged();
}
}
@inject IJSRuntime JS
<li>
@message
<button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>
@code {
private string message = "Select one of these list item buttons.";
private string display = "inline-block";
private MessageUpdateInvokeHelper? messageUpdateInvokeHelper;
protected override void OnInitialized()
{
messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
}
protected async Task InteropCall()
{
if (messageUpdateInvokeHelper is not null)
{
await JS.InvokeVoidAsync("updateMessageCaller",
DotNetObjectReference.Create(messageUpdateInvokeHelper));
}
}
private void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
StateHasChanged();
}
}
@inject IJSRuntime JS
<li>
@message
<button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>
@code {
private string message = "Select one of these list item buttons.";
private string display = "inline-block";
private MessageUpdateInvokeHelper? messageUpdateInvokeHelper;
protected override void OnInitialized()
{
messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
}
protected async Task InteropCall()
{
if (messageUpdateInvokeHelper is not null)
{
await JS.InvokeVoidAsync("updateMessageCaller",
DotNetObjectReference.Create(messageUpdateInvokeHelper));
}
}
private void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
StateHasChanged();
}
}
@inject IJSRuntime JS
<li>
@message
<button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>
@code {
private string message = "Select one of these list item buttons.";
private string display = "inline-block";
private MessageUpdateInvokeHelper messageUpdateInvokeHelper;
protected override void OnInitialized()
{
messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
}
protected async Task InteropCall()
{
await JS.InvokeVoidAsync("updateMessageCaller",
DotNetObjectReference.Create(messageUpdateInvokeHelper));
}
private void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
StateHasChanged();
}
}
@inject IJSRuntime JS
<li>
@message
<button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>
@code {
private string message = "Select one of these list item buttons.";
private string display = "inline-block";
private MessageUpdateInvokeHelper messageUpdateInvokeHelper;
protected override void OnInitialized()
{
messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
}
protected async Task InteropCall()
{
await JS.InvokeVoidAsync("updateMessageCaller",
DotNetObjectReference.Create(messageUpdateInvokeHelper));
}
private void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
StateHasChanged();
}
}
StateHasChanged
element jest wywoływany w celu zaktualizowania interfejsu użytkownika, gdy message
jest ustawiony w elem UpdateMessage
. Jeśli StateHasChanged
nie jest wywoływana, nie ma możliwości, aby wiedzieć, Blazor że interfejs użytkownika powinien zostać zaktualizowany po wywołaniu Action .
Poniższy składnik nadrzędny zawiera cztery elementy listy, z których każde jest wystąpieniem ListItem1
składnika.
CallDotnet6.razor
:
@page "/call-dotnet-6"
<PageTitle>Call .NET 6</PageTitle>
<h1>Call .NET Example 6</h1>
<ul>
<ListItem1 />
<ListItem1 />
<ListItem1 />
<ListItem1 />
</ul>
CallDotnet6.razor
:
@page "/call-dotnet-6"
<PageTitle>Call .NET 6</PageTitle>
<h1>Call .NET Example 6</h1>
<ul>
<ListItem1 />
<ListItem1 />
<ListItem1 />
<ListItem1 />
</ul>
CallDotNetExample6.razor
:
@page "/call-dotnet-example-6"
<h1>Call .NET Example 6</h1>
<ul>
<ListItem1 />
<ListItem1 />
<ListItem1 />
<ListItem1 />
</ul>
CallDotNetExample6.razor
:
@page "/call-dotnet-example-6"
<h1>Call .NET Example 6</h1>
<ul>
<ListItem1 />
<ListItem1 />
<ListItem1 />
<ListItem1 />
</ul>
CallDotNetExample6.razor
:
@page "/call-dotnet-example-6"
<h1>Call .NET Example 6</h1>
<ul>
<ListItem1 />
<ListItem1 />
<ListItem1 />
<ListItem1 />
</ul>
CallDotNetExample6.razor
:
@page "/call-dotnet-example-6"
<h1>Call .NET Example 6</h1>
<ul>
<ListItem1 />
<ListItem1 />
<ListItem1 />
<ListItem1 />
</ul>
Na poniższej ilustracji przedstawiono renderowany składnik nadrzędny po wybraniu drugiego InteropCall
przycisku:
ListItem1
Drugi składnik wyświetliłUpdateMessage Called!
komunikat.- Przycisk
InteropCall
drugiegoListItem1
składnika nie jest widoczny, ponieważ właściwość CSSdisplay
przycisku jest ustawiona nanone
wartość .
Metoda .NET wystąpienia składnika wywoływana z DotNetObjectReference
przypisanej do właściwości elementu
Przypisanie DotNetObjectReference elementu do właściwości elementu HTML umożliwia wywoływanie metod .NET w wystąpieniu składnika:
- Przechwycono odwołanie do elementu (ElementReference).
- W metodzie
OnAfterRender{Async}
składnika funkcja JavaScript (JS) jest wywoływana z odwołaniem do elementu i wystąpieniem DotNetObjectReferenceskładnika jako . Funkcja JS dołącza element DotNetObjectReference do elementu we właściwości . - Po wywołaniu zdarzenia elementu ( JS na przykład
onclick
), dołączony DotNetObjectReference element jest używany do wywoływania metody .NET.
Podobnie jak w przypadku podejścia opisanego w sekcji Klasa pomocnika metody platformy .NET wystąpienia składnika, to podejście jest przydatne w scenariuszach, w których używanie statycznych metod platformy .NET nie ma zastosowania:
- Gdy na tej samej stronie jest renderowanych kilka składników tego samego typu.
- W aplikacjach po stronie serwera z wieloma użytkownikami jednocześnie używających tego samego składnika.
- Metoda .NET jest wywoływana ze JS zdarzenia (na przykład
onclick
), a nie ze Blazor zdarzenia (na przykład@onclick
).
W poniższym przykładzie:
- Składnik zawiera kilka
ListItem2
składników, które są składnikiem udostępnionym. - Każdy
ListItem2
składnik składa się z komunikatu<span>
o elemencie listy, a drugi<span>
z właściwością CSS ustawionądisplay
nainline-block
wartość na potrzeby wyświetlania. - Po wybraniu
ListItem2
ListItem2
UpdateMessage
elementu listy składników metoda zmienia tekst elementu listy w pierwszym<span>
i ukrywa drugi<span>
, ustawiając jegodisplay
właściwość na .none
Poniższa assignDotNetHelper
JS funkcja przypisuje element DotNetObjectReference do elementu we właściwości o nazwie dotNetHelper
. Poniższa interopCall
JS funkcja używa DotNetObjectReference elementu dla przekazanego elementu, aby wywołać metodę .NET o nazwie UpdateMessage
.
ListItem2.razor.js
:
export function assignDotNetHelper(element, dotNetHelper) {
element.dotNetHelper = dotNetHelper;
}
export async function interopCall(element) {
await element.dotNetHelper.invokeMethodAsync('UpdateMessage');
}
ListItem2.razor.js
:
export function assignDotNetHelper(element, dotNetHelper) {
element.dotNetHelper = dotNetHelper;
}
export async function interopCall(element) {
await element.dotNetHelper.invokeMethodAsync('UpdateMessage');
}
<script>
window.assignDotNetHelper = (element, dotNetHelper) => {
element.dotNetHelper = dotNetHelper;
}
window.interopCall = async (element) => {
await element.dotNetHelper.invokeMethodAsync('UpdateMessage');
}
</script>
Uwaga
Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Lokalizacja języka JavaScript w aplikacjach ASP.NET CoreBlazor.
W poprzednim przykładzie nazwa dotNetHelper
zmiennej jest dowolna i można ją zmienić na dowolną preferowaną nazwę.
Poniższy ListItem2
składnik jest składnikiem udostępnionym, który może być używany dowolną liczbę razy w składniku nadrzędnym i tworzy elementy listy () dla listy HTML (<li>...</li>
<ul>...</ul>
lub <ol>...</ol>
).
Każde ListItem2
wystąpienie składnika wywołuje assignDotNetHelper
JS funkcję w OnAfterRenderAsync
elemencie z odwołaniem do elementu (pierwszym <span>
elementem elementu listy) i wystąpieniem składnika jako DotNetObjectReference.
ListItem2
Po wybraniu komunikatu <span>
składnika jest wywoływany <span>
przekazywanie interopCall
elementu jako parametru (this
), który wywołuje UpdateMessage
metodę .NET. W UpdateMessage
pliku StateHasChanged
jest wywoływany w celu zaktualizowania interfejsu użytkownika, gdy message
jest ustawiony, a display
właściwość drugiego <span>
jest aktualizowana. Jeśli StateHasChanged
nie jest wywoływana, nie ma możliwości, aby wiedzieć, Blazor że interfejs użytkownika powinien zostać zaktualizowany po wywołaniu metody.
Element DotNetObjectReference jest usuwany, gdy składnik jest usuwany.
ListItem2.razor
:
@inject IJSRuntime JS
@implements IAsyncDisposable
<li>
<span style="font-weight:bold;color:@color" @ref="elementRef"
@onclick="CallJSToInvokeDotnet">
@message
</span>
<span style="display:@display">
Not Updated Yet!
</span>
</li>
@code {
private IJSObjectReference? module;
private DotNetObjectReference<ListItem2>? objRef;
private ElementReference elementRef;
private string display = "inline-block";
private string message = "Select one of these list items.";
private string color = "initial";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Components/ListItem2.razor.js");
objRef = DotNetObjectReference.Create(this);
await module.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
}
}
public async void CallJSToInvokeDotnet()
{
if (module is not null)
{
await module.InvokeVoidAsync("interopCall", elementRef);
}
}
[JSInvokable]
public void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
color = "MediumSeaGreen";
StateHasChanged();
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
objRef?.Dispose();
}
}
@inject IJSRuntime JS
@implements IAsyncDisposable
<li>
<span style="font-weight:bold;color:@color" @ref="elementRef"
@onclick="CallJSToInvokeDotnet">
@message
</span>
<span style="display:@display">
Not Updated Yet!
</span>
</li>
@code {
private IJSObjectReference? module;
private DotNetObjectReference<ListItem2>? objRef;
private ElementReference elementRef;
private string display = "inline-block";
private string message = "Select one of these list items.";
private string color = "initial";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Components/ListItem2.razor.js");
objRef = DotNetObjectReference.Create(this);
await module.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
}
}
public async void CallJSToInvokeDotnet()
{
if (module is not null)
{
await module.InvokeVoidAsync("interopCall", elementRef);
}
}
[JSInvokable]
public void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
color = "MediumSeaGreen";
StateHasChanged();
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
objRef?.Dispose();
}
}
@inject IJSRuntime JS
<li>
<span @ref="elementRef" onclick="interopCall(this)">@message</span>
<span style="display:@display">Not Updated Yet!</span>
</li>
@code {
private DotNetObjectReference<ListItem2>? objRef;
private ElementReference elementRef;
private string display = "inline-block";
private string message = "Select one of these list items.";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
objRef = DotNetObjectReference.Create(this);
await JS.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
}
}
[JSInvokable]
public void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
StateHasChanged();
}
public void Dispose() => objRef?.Dispose();
}
@inject IJSRuntime JS
<li>
<span @ref="elementRef" onclick="interopCall(this)">@message</span>
<span style="display:@display">Not Updated Yet!</span>
</li>
@code {
private DotNetObjectReference<ListItem2>? objRef;
private ElementReference elementRef;
private string display = "inline-block";
private string message = "Select one of these list items.";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
objRef = DotNetObjectReference.Create(this);
await JS.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
}
}
[JSInvokable]
public void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
StateHasChanged();
}
public void Dispose() => objRef?.Dispose();
}
@inject IJSRuntime JS
<li>
<span @ref="elementRef" onclick="interopCall(this)">@message</span>
<span style="display:@display">Not Updated Yet!</span>
</li>
@code {
private DotNetObjectReference<ListItem2> objRef;
private ElementReference elementRef;
private string display = "inline-block";
private string message = "Select one of these list items.";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
objRef = DotNetObjectReference.Create(this);
await JS.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
}
}
[JSInvokable]
public void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
StateHasChanged();
}
public void Dispose() => objRef?.Dispose();
}
@inject IJSRuntime JS
<li>
<span @ref="elementRef" onclick="interopCall(this)">@message</span>
<span style="display:@display">Not Updated Yet!</span>
</li>
@code {
private DotNetObjectReference<ListItem2> objRef;
private ElementReference elementRef;
private string display = "inline-block";
private string message = "Select one of these list items.";
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
objRef = DotNetObjectReference.Create(this);
await JS.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
}
}
[JSInvokable]
public void UpdateMessage()
{
message = "UpdateMessage Called!";
display = "none";
StateHasChanged();
}
public void Dispose() => objRef?.Dispose();
}
Poniższy składnik nadrzędny zawiera cztery elementy listy, z których każde jest wystąpieniem ListItem2
składnika.
CallDotnet7.razor
:
@page "/call-dotnet-7"
<PageTitle>Call .NET 7</PageTitle>
<h1>Call .NET Example 7</h1>
<ul>
<ListItem2 />
<ListItem2 />
<ListItem2 />
<ListItem2 />
</ul>
CallDotnet7.razor
:
@page "/call-dotnet-7"
<PageTitle>Call .NET 7</PageTitle>
<h1>Call .NET Example 7</h1>
<ul>
<ListItem2 />
<ListItem2 />
<ListItem2 />
<ListItem2 />
</ul>
CallDotNetExample7.razor
:
@page "/call-dotnet-example-7"
<h1>Call .NET Example 7</h1>
<ul>
<ListItem2 />
<ListItem2 />
<ListItem2 />
<ListItem2 />
</ul>
CallDotNetExample7.razor
:
@page "/call-dotnet-example-7"
<h1>Call .NET Example 7</h1>
<ul>
<ListItem2 />
<ListItem2 />
<ListItem2 />
<ListItem2 />
</ul>
CallDotNetExample7.razor
:
@page "/call-dotnet-example-7"
<h1>Call .NET Example 7</h1>
<ul>
<ListItem2 />
<ListItem2 />
<ListItem2 />
<ListItem2 />
</ul>
CallDotNetExample7.razor
:
@page "/call-dotnet-example-7"
<h1>Call .NET Example 7</h1>
<ul>
<ListItem2 />
<ListItem2 />
<ListItem2 />
<ListItem2 />
</ul>
Synchroniczne międzyoperajności JS w składnikach po stronie klienta
Ta sekcja dotyczy tylko składników po stronie klienta.
JS wywołania międzyoperacyjne są asynchroniczne, niezależnie od tego, czy wywoływany kod jest synchroniczny, czy asynchroniczny. Wywołania są asynchroniczne, aby upewnić się, że składniki są zgodne z trybami renderowania po stronie serwera i po stronie klienta. Na serwerze wszystkie JS wywołania międzyoperacyjne muszą być asynchroniczne, ponieważ są wysyłane za pośrednictwem połączenia sieciowego.
Jeśli wiesz, że składnik działa tylko w zestawie WebAssembly, możesz wykonać synchroniczne wywołania międzyoperacyjne JS . Ma to nieco mniejsze obciążenie niż wykonywanie wywołań asynchronicznych i może spowodować zmniejszenie liczby cykli renderowania, ponieważ nie ma stanu pośredniego podczas oczekiwania na wyniki.
Aby wykonać wywołanie synchroniczne z języka JavaScript do platformy .NET w składniku po stronie klienta, użyj polecenia DotNet.invokeMethod
zamiast DotNet.invokeMethodAsync
.
Wywołania synchroniczne działają, jeśli:
Lokalizacja języka JavaScript
Załaduj kod JavaScript (JS) przy użyciu dowolnego podejścia opisanego w artykule dotyczącym lokalizacji języka JavaScript:
- Ładowanie skryptu w znaczniku
<head>
(zazwyczaj niezalecane) - Ładowanie skryptu w znaczniku
<body>
- Ładowanie skryptu z zewnętrznego pliku JavaScript (
.js
) znajdującego się w tej samej lokalizacji co składnik - Ładowanie skryptu z zewnętrznego pliku JavaScript (
.js
) - Wstrzykiwanie skryptu przed uruchomieniem lub po Blazor nim
Ładowanie JS modułów JS zostało opisane w tym artykule w sekcji Izolacja języka JavaScript w modułach Języka JavaScript.
Ostrzeżenie
Umieść <script>
tag tylko w pliku składnika (.razor
), jeśli składnik ma gwarancję wdrożenia statycznego renderowania po stronie serwera (statyczny SSR), ponieważ <script>
tag nie może być aktualizowany dynamicznie.
Ostrzeżenie
Nie umieszczaj tagu <script>
w pliku składnika (.razor
), ponieważ <script>
tag nie może być aktualizowany dynamicznie.
Izolacja języka JavaScript w modułach języka JavaScript
Platforma Blazor włącza izolację języka JavaScript (JS) w standardowych modułach języka JavaScript (Specyfikacja ECMAScript). Ładowanie modułu JavaScript działa tak samo jak w Blazor przypadku innych typów aplikacji internetowych i możesz dostosować sposób definiowania modułów w aplikacji. Aby zapoznać się z przewodnikiem dotyczącym używania modułów Języka JavaScript, zobacz Artykuł MdN Web Docs: JavaScript modules (Dokumentacja internetowa mdN: moduły Języka JavaScript).
Izolacja języka JS zapewnia następujące korzyści:
- Zaimportowany kod JS nie zanieczyszcza już globalnej przestrzeni nazw.
- Użytkownicy biblioteki i składników nie są zobowiązani do zaimportowania powiązanego kodu JS.
Aby uzyskać więcej informacji, zobacz Wywoływanie funkcji języka JavaScript z metod platformy .NET na platformie ASP.NET Core Blazor.
Importowanie dynamiczne za pomocą import()
operatora jest obsługiwane w przypadku platformy ASP.NET Core i Blazor:
if ({CONDITION}) import("/additionalModule.js");
W poprzednim przykładzie symbol zastępczy reprezentuje sprawdzanie warunkowe, aby określić, {CONDITION}
czy moduł powinien zostać załadowany.
Aby uzyskać informacje o zgodności przeglądarki, zobacz Czy mogę używać: moduły JavaScript: import dynamiczny.
Unikaj odwołań do obiektów okrągłych
Obiekty zawierające odwołania cykliczne nie mogą być serializowane na kliencie dla jednego z następujących obiektów:
- Wywołania metody .NET.
- Wywołania metody Języka JavaScript z języka C#, gdy zwracany typ zawiera odwołania cykliczne.
Obsługa tablic bajtów
Blazor obsługuje zoptymalizowaną międzyoperacyjną tablicę bajtów JavaScript (JS), która pozwala uniknąć kodowania/dekodowania tablic bajtowych do base64. W poniższym przykładzie użyto JS międzyoperajności, aby przekazać tablicę bajtów do platformy .NET.
sendByteArray
JS Podaj funkcję. Funkcja jest wywoływana statycznie, która zawiera parametr nazwy zestawu w wywołaniu invokeMethodAsync
przez przycisk w składniku i nie zwraca wartości:
CallDotnet8.razor.js
:
export function sendByteArray() {
const data = new Uint8Array([0x45, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69,
0x6e, 0x67, 0x27, 0x73, 0x20, 0x73, 0x68, 0x69, 0x6e, 0x79, 0x2c,
0x20, 0x43, 0x61, 0x70, 0x74, 0x61, 0x69, 0x6e, 0x2e, 0x20, 0x4e,
0x6f, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x72, 0x65, 0x74, 0x2e]);
DotNet.invokeMethodAsync('BlazorSample', 'ReceiveByteArray', data)
.then(str => {
alert(str);
});
}
export function addHandlers() {
const btn = document.getElementById("btn");
btn.addEventListener("click", sendByteArray);
}
<script>
window.sendByteArray = () => {
const data = new Uint8Array([0x45,0x76,0x65,0x72,0x79,0x74,0x68,0x69,
0x6e,0x67,0x27,0x73,0x20,0x73,0x68,0x69,0x6e,0x79,0x2c,
0x20,0x43,0x61,0x70,0x74,0x61,0x69,0x6e,0x2e,0x20,0x4e,
0x6f,0x74,0x20,0x74,0x6f,0x20,0x66,0x72,0x65,0x74,0x2e]);
DotNet.invokeMethodAsync('BlazorSample', 'ReceiveByteArray', data)
.then(str => {
alert(str);
});
};
</script>
Uwaga
Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Lokalizacja języka JavaScript w aplikacjach ASP.NET CoreBlazor.
CallDotnet8.razor
:
@page "/call-dotnet-8"
@using System.Text
@implements IAsyncDisposable
@inject IJSRuntime JS
<PageTitle>Call .NET 8</PageTitle>
<h1>Call .NET Example 8</h1>
<p>
<button id="btn">Send Bytes</button>
</p>
<p>
Quote ©2005 <a href="https://www.uphe.com">Universal Pictures</a>:
<a href="https://www.uphe.com/movies/serenity-2005">Serenity</a><br>
<a href="https://www.imdb.com/name/nm0821612/">Jewel Staite on IMDB</a>
</p>
@code {
private IJSObjectReference? module;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Components/Pages/CallDotnet8.razor.js");
await module.InvokeVoidAsync("addHandlers");
}
}
[JSInvokable]
public static Task<string> ReceiveByteArray(byte[] receivedBytes) =>
Task.FromResult(Encoding.UTF8.GetString(receivedBytes, 0,
receivedBytes.Length));
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
}
CallDotnet8.razor
:
@page "/call-dotnet-8"
@using System.Text
@implements IAsyncDisposable
@inject IJSRuntime JS
<PageTitle>Call .NET 8</PageTitle>
<h1>Call .NET Example 8</h1>
<p>
<button id="btn">Send Bytes</button>
</p>
<p>
Quote ©2005 <a href="https://www.uphe.com">Universal Pictures</a>:
<a href="https://www.uphe.com/movies/serenity-2005">Serenity</a><br>
<a href="https://www.imdb.com/name/nm0821612/">Jewel Staite on IMDB</a>
</p>
@code {
private IJSObjectReference? module;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./Components/Pages/CallDotnet8.razor.js");
await module.InvokeVoidAsync("addHandlers");
}
}
[JSInvokable]
public static Task<string> ReceiveByteArray(byte[] receivedBytes) =>
Task.FromResult(Encoding.UTF8.GetString(receivedBytes, 0,
receivedBytes.Length));
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
}
CallDotNetExample8.razor
:
@page "/call-dotnet-example-8"
@using System.Text
<PageTitle>Call .NET 8</PageTitle>
<h1>Call .NET Example 8</h1>
<p>
<button onclick="sendByteArray()">Send Bytes</button>
</p>
<p>
Quote ©2005 <a href="https://www.uphe.com">Universal Pictures</a>:
<a href="https://www.uphe.com/movies/serenity-2005">Serenity</a><br>
<a href="https://www.imdb.com/name/nm0821612/">Jewel Staite on IMDB</a>
</p>
@code {
[JSInvokable]
public static Task<string> ReceiveByteArray(byte[] receivedBytes)
{
return Task.FromResult(
Encoding.UTF8.GetString(receivedBytes, 0, receivedBytes.Length));
}
}
CallDotNetExample8.razor
:
@page "/call-dotnet-example-8"
@using System.Text
<h1>Call .NET Example 8</h1>
<p>
<button onclick="sendByteArray()">Send Bytes</button>
</p>
<p>
Quote ©2005 <a href="https://www.uphe.com">Universal Pictures</a>:
<a href="https://www.uphe.com/movies/serenity-2005">Serenity</a><br>
<a href="https://www.imdb.com/name/nm0821612/">Jewel Staite on IMDB</a>
</p>
@code {
[JSInvokable]
public static Task<string> ReceiveByteArray(byte[] receivedBytes)
{
return Task.FromResult(
Encoding.UTF8.GetString(receivedBytes, 0, receivedBytes.Length));
}
}
Aby uzyskać informacje na temat używania tablicy bajtów podczas wywoływania języka JavaScript z platformy .NET, zobacz Wywoływanie funkcji Języka JavaScript z metod platformy .NET w programie ASP.NET Core Blazor.
Przesyłanie strumieniowe z języka JavaScript do platformy .NET
Blazor obsługuje przesyłanie strumieniowe danych bezpośrednio z języka JavaScript do platformy .NET. Strumienie są żądane przy użyciu interfejsu Microsoft.JSInterop.IJSStreamReference
.
Microsoft.JSInterop.IJSStreamReference.OpenReadStreamAsync
Zwraca element Stream i używa następujących parametrów:
maxAllowedSize
: Maksymalna liczba bajtów dozwolona dla operacji odczytu z języka JavaScript, która domyślnie wynosi 512 000 bajtów, jeśli nie zostanie określona.cancellationToken
: A CancellationToken do anulowania odczytu.
W języku JavaScript:
function streamToDotNet() {
return new Uint8Array(10000000);
}
W kodzie języka C#:
var dataReference =
await JS.InvokeAsync<IJSStreamReference>("streamToDotNet");
using var dataReferenceStream =
await dataReference.OpenReadStreamAsync(maxAllowedSize: 10_000_000);
var outputPath = Path.Combine(Path.GetTempPath(), "file.txt");
using var outputFileStream = File.OpenWrite(outputPath);
await dataReferenceStream.CopyToAsync(outputFileStream);
W powyższym przykładzie:
JS
jest wystąpieniem wstrzykniętym IJSRuntime . IJSRuntime program jest zarejestrowany przez platformę Blazor .- Element
dataReferenceStream
jest zapisywany na dysku (file.txt
) w ścieżce folderu tymczasowego bieżącego użytkownika (GetTempPath).
Wywoływanie funkcji Języka JavaScript z metod platformy .NET w programie ASP.NET Core Blazor obejmuje operację odwrotną, przesyłaną strumieniowo z platformy .NET do języka JavaScript przy użyciu elementu DotNetStreamReference.
ASP.NET Core Blazor przekazywania plików obejmuje sposób przekazywania pliku w programie Blazor. Przykład formularzy, który przesyła strumieniowo dane w składniku po stronie serwera, zobacz Rozwiązywanie problemów z formularzami <textarea>
ASP.NET CoreBlazor.
Interopcja języka JavaScript [JSImport]
/[JSExport]
Ta sekcja dotyczy składników po stronie klienta.
Alternatywą dla interakcji z językiem JavaScript (JS) w składnikach po stronie klienta przy użyciu JS Blazormechanizmu międzyoperacyjnego opartego na interfejsie IJSRuntime jest/JS[JSImport]
[JSExport]
dostępny interfejs API międzyoperacyjny dla aplikacji przeznaczonych dla platformy .NET 7 lub nowszej.
Aby uzyskać więcej informacji, zobacz JavaScript JSImport/JSExport interop with ASP.NET Core (Interopcja javaScript JSImport/JSExport with ASP.NET Core Blazor).
Usuwanie odwołań do obiektów międzyoperacyjnych języka JavaScript
Przykłady w artykułach międzyoperacyjnych języka JavaScript (JS) przedstawiają typowe wzorce usuwania obiektów:
Podczas wywoływania platformy .NET z programu , zgodnie z JSopisem w tym artykule, należy usunąć utworzony element DotNetObjectReference z platformy .NET lub JS uniknąć wycieku pamięci platformy .NET.
Podczas wywoływania JS z platformy .NET zgodnie z opisem w temacie Wywoływanie funkcji JavaScript z metod platformy .NET w programie ASP.NET Core Blazornależy usunąć wszystkie utworzone zIJSInProcessObjectReference//
JSObjectReference
IJSObjectReferenceplatformy .NET lub zJS, aby uniknąć wycieku JS pamięci.
JS Odwołania do obiektów międzyoperacyjności są implementowane jako mapowane przez identyfikator po stronie wywołania międzyoperacyjnego JS , które tworzy odwołanie. Gdy usuwanie obiektu jest inicjowane z platformy .NET lub JS po stronie, Blazor usuwa wpis z mapy, a obiekt może zostać odśmiecany, o ile nie ma innego silnego odwołania do obiektu.
Co najmniej zawsze usuwaj obiekty utworzone po stronie platformy .NET, aby uniknąć wycieku pamięci zarządzanej platformy .NET.
Zadania oczyszczania modelu DOM podczas usuwania składników
Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor JavaScript interoperability (JS interop).
Wywołania międzyoperacyjne języka JavaScript bez obwodu
Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor JavaScript interoperability (JS interop).
Dodatkowe zasoby
- Wywoływanie funkcji języka JavaScript z metod platformy .NET na platformie ASP.NET Core Blazor
InteropComponent.razor
example (dotnet/AspNetCore
Gałąź repozytoriummain
GitHub):main
Gałąź reprezentuje bieżący rozwój jednostki produktu dla następnej wersji ASP.NET Core. Aby wybrać gałąź dla innej wersji (na przykładrelease/{VERSION}
, gdzie{VERSION}
symbol zastępczy jest wersją wydania), użyj listy rozwijanej Przełącz gałęzie lub tagi , aby wybrać gałąź. W przypadku gałęzi, która już nie istnieje, użyj karty Tagi , aby znaleźć interfejs API (na przykładv7.0.0
).- Interakcja z dom
- Blazorprzykładowe repozytorium GitHub () (
dotnet/blazor-samples
jak pobrać) - Obsługa błędów w aplikacjach ASP.NET Core Blazor (sekcja międzyoperacji w języku JavaScript)
- Ograniczenie zagrożeń: metody platformy .NET wywoływane z przeglądarki