Współdziałanie języka JavaScript [JSImport]
/[JSExport]
z platformą ASP.NET Core Blazor
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.
Ostrzeżenie
Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz .NET i .NET Core Support Policy (Zasady obsługi platformy .NET Core). Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.
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ą, zapoznaj się z wersją tego artykułu platformy .NET 8.
W tym artykule wyjaśniono, jak korzystać z języka JavaScript (JS) w składnikach po stronie klienta przy użyciu międzyoperacyjnego interfejsu API języka JavaScript (JS) [JSImport]
/[JSExport]
wydanego dla aplikacji, które przyjmują platformę .NET 7 lub nowszą.
Blazor zapewnia własny JS mechanizm międzyoperacyjny oparty na interfejsie IJSRuntime . BlazorWspółdziałanie JS międzyoperajności jest jednolicie obsługiwane w Blazor trybach renderowania i w przypadku Blazor Hybrid aplikacji. IJSRuntime Umożliwia również autorom bibliotek tworzenie JS bibliotek międzyoperacyjności na potrzeby udostępniania w ekosystemie Blazor i pozostaje zalecanym podejściem do JS międzyoperacyjności w programie Blazor. Odwiedź następujące artykuły:
- Wywoływanie funkcji języka JavaScript z metod platformy .NET na platformie ASP.NET Core Blazor
- Wywoływanie metod platformy .NET z funkcji języka JavaScript z na platformie ASP.NET Core Blazor
W tym artykule opisano alternatywne JS podejście międzyoperamentowe specyficzne dla składników po stronie klienta wykonywanych w zestawie WebAssembly. Te podejścia są odpowiednie, gdy oczekujesz, że będzie działać tylko w trybie WebAssembly po stronie klienta. Autorzy bibliotek mogą użyć tych metod optymalizacji JS międzyoperacyjnej, sprawdzając podczas wykonywania kodu, czy aplikacja jest uruchomiona w zestawie WebAssembly w przeglądarce (OperatingSystem.IsBrowser). Metody opisane w tym artykule powinny służyć do zastępowania przestarzałego, niezamężnego JS interfejsu API międzyoperacyjności podczas migracji do platformy .NET 7 lub nowszej.
Uwaga
Ten artykuł koncentruje się na JS współdziałaniu składników po stronie klienta. Aby uzyskać wskazówki dotyczące wywoływania platformy .NET w aplikacjach JavaScript, zobacz Uruchamianie platformy .NET w języku JavaScript.
Przestarzały interfejs API międzyoperacyjny języka JavaScript
Unmarshalled JS interop using IJSUnmarshalledRuntime API is przestarzałe w ASP.NET Core na platformie .NET 7 lub nowszym. Postępuj zgodnie ze wskazówkami w tym artykule, aby zastąpić przestarzały interfejs API.
Wymagania wstępne
Pobierz i zainstaluj program .NET 7 lub nowszy , jeśli nie został jeszcze zainstalowany w systemie lub jeśli system nie ma zainstalowanej najnowszej wersji.
Przestrzeń nazw
Interfejs JS API międzyoperacyjnych (JSHost.ImportAsync) opisany w tym artykule jest kontrolowany przez atrybuty w System.Runtime.InteropServices.JavaScript przestrzeni nazw.
Włączanie niebezpiecznych bloków
AllowUnsafeBlocks Włącz właściwość w pliku projektu aplikacji, która zezwala generatorowi kodu w kompilatorze Roslyn na używanie wskaźników dla JS międzyoperacyjności:
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
Ostrzeżenie
Interfejs JS API międzyoperajności wymaga włączenia funkcji AllowUnsafeBlocks. Należy zachować ostrożność podczas implementowania własnego niebezpiecznego kodu w aplikacjach platformy .NET, co może powodować zagrożenia bezpieczeństwa i stabilności. Aby uzyskać więcej informacji, zobacz Niebezpieczny kod, typy wskaźników i wskaźniki funkcji.
Razor zestawiona JS biblioteka klas (RCL) nie jest obsługiwana
Ogólnie rzecz biorąc, obsługa JS lokalizacji międzyoperacyjnej IJSRuntimeJS (lokalizacja Języka JavaScript w aplikacjach ASP.NET CoreBlazor) jest również dostępna dla międzyoperacji opisanej [JSImport]
/[JSExport]
w tym artykule. Jedyną nieobsługiwaną JS funkcją Razor lokalizacji jest sortowanie JS w bibliotece klas (RCL).
Zamiast używać sortowania JS w liście RCL, umieść JS plik w folderze listy RCL i odwołaj się do niego przy użyciu zwykłej ścieżki dla zasobów statycznych listy RCL wwwroot
:
_content/{PACKAGE ID}/{PATH}/{FILE NAME}.js
- Symbol
{PACKAGE ID}
zastępczy to identyfikator pakietu listy RCL (lub nazwa biblioteki dla biblioteki klas). - Symbol
{PATH}
zastępczy to ścieżka do pliku. - Symbol
{FILE NAME}
zastępczy to nazwa pliku.
Mimo że sortowanie JS na liście RCL nie jest obsługiwane przez[JSExport]
[JSImport]
/międzyoperacyjnie, można zachować JS zorganizowane pliki, wykonując jedną lub obie z następujących metod:
- Nadaj plikowi JS nazwę taką samą jak składnik, w którym JS jest używany. W przypadku składnika w liście RCL o nazwie
CallJavaScriptFromLib
(CallJavaScriptFromLib.razor
) nadaj plikowiCallJavaScriptFromLib.js
nazwę w folderzewwwroot
. - Umieść pliki specyficzne dla JS składników w
Components
folderze wewnątrz folderu listy RCLwwwroot
i użyj ciągu "Components
" w ścieżce do pliku:_content/{PACKAGE ID}/Components/CallJavaScriptFromLib.js
.
Wywoływanie kodu JavaScript z platformy .NET
W tej sekcji opisano sposób wywoływania JS funkcji z platformy .NET.
W poniższym składniku CallJavaScript1
:
- Moduł
CallJavaScript1
jest importowany asynchronicznie ze sprowadzonego JS pliku za pomocą polecenia JSHost.ImportAsync. - Zaimportowana
getMessage
JS funkcja jest wywoływana przezGetWelcomeMessage
funkcję . - Zwrócony ciąg komunikatu powitalnego jest wyświetlany w interfejsie użytkownika za pośrednictwem
message
pola.
CallJavaScript1.razor
:
@page "/call-javascript-1"
@rendermode InteractiveWebAssembly
@using System.Runtime.InteropServices.JavaScript
<h1>
JS <code>[JSImport]</code>/<code>[JSExport]</code> Interop
(Call JS Example 1)
</h1>
@(message is not null ? message : string.Empty)
@code {
private string? message;
protected override async Task OnInitializedAsync()
{
await JSHost.ImportAsync("CallJavaScript1",
"../Components/Pages/CallJavaScript1.razor.js");
message = GetWelcomeMessage();
}
}
@page "/call-javascript-1"
@using System.Runtime.InteropServices.JavaScript
<h1>
JS <code>[JSImport]</code>/<code>[JSExport]</code> Interop
(Call JS Example 1)
</h1>
@(message is not null ? message : string.Empty)
@code {
private string? message;
protected override async Task OnInitializedAsync()
{
await JSHost.ImportAsync("CallJavaScript1",
"../Pages/CallJavaScript1.razor.js");
message = GetWelcomeMessage();
}
}
Uwaga
Dołącz kod OperatingSystem.IsBrowser sprawdzania warunkowego, aby upewnić się, że JS interop jest wywoływany tylko przez składnik renderowany na kliencie. Jest to ważne w przypadku bibliotek/pakietów NuGet przeznaczonych dla składników po stronie serwera, które nie mogą wykonać kodu dostarczonego przez ten JS interfejs API międzyoperacyjnej.
Aby zaimportować JS funkcję w celu wywołania jej z języka C#, użyj atrybutu [JSImport]
w podpisie metody języka C#, który pasuje do JS podpisu funkcji. Pierwszy parametr atrybutu to nazwa JS funkcji do zaimportowania, a drugi parametr to nazwa modułuJS.[JSImport]
W poniższym przykładzie jest JS to funkcja, getMessage
która zwraca string
element dla modułu o nazwie CallJavaScript1
. Sygnatura metody języka C#jest zgodna: do funkcji nie są przekazywane JS żadne parametry, a JS funkcja zwraca string
wartość . Funkcja jest wywoływana JS w GetWelcomeMessage
kodzie języka C#.
CallJavaScript1.razor.cs
:
using System.Runtime.InteropServices.JavaScript;
using System.Runtime.Versioning;
namespace BlazorSample.Components.Pages;
[SupportedOSPlatform("browser")]
public partial class CallJavaScript1
{
[JSImport("getMessage", "CallJavaScript1")]
internal static partial string GetWelcomeMessage();
}
Przestrzeń nazw aplikacji dla poprzedniej klasy częściowej CallJavaScript1
to BlazorSample
. Przestrzeń nazw składnika to BlazorSample.Components.Pages
. Jeśli używasz poprzedniego składnika w lokalnej aplikacji testowej, zaktualizuj przestrzeń nazw tak, aby odpowiadała aplikacji. Na przykład przestrzeń nazw to ContosoApp.Components.Pages
, jeśli przestrzeń nazw aplikacji to ContosoApp
. Aby uzyskać więcej informacji, zobacz ASP.NET Podstawowe Razor składniki.
using System.Runtime.InteropServices.JavaScript;
using System.Runtime.Versioning;
namespace BlazorSample.Pages;
[SupportedOSPlatform("browser")]
public partial class CallJavaScript1
{
[JSImport("getMessage", "CallJavaScript1")]
internal static partial string GetWelcomeMessage();
}
Przestrzeń nazw aplikacji dla poprzedniej klasy częściowej CallJavaScript1
to BlazorSample
. Przestrzeń nazw składnika to BlazorSample.Pages
. Jeśli używasz poprzedniego składnika w lokalnej aplikacji testowej, zaktualizuj przestrzeń nazw tak, aby odpowiadała aplikacji. Na przykład przestrzeń nazw to ContosoApp.Pages
, jeśli przestrzeń nazw aplikacji to ContosoApp
. Aby uzyskać więcej informacji, zobacz ASP.NET Podstawowe Razor składniki.
W zaimportowanym podpisie metody można użyć typów platformy .NET dla parametrów i wartości zwracanych, które są automatycznie obsługiwane przez środowisko uruchomieniowe. Służy JSMarshalAsAttribute<T> do kontrolowania sposobu stosowania importowanych parametrów metody. Na przykład możesz wybrać przeprowadzanie marshalingu long
jako lub System.Runtime.InteropServices.JavaScript.JSType.BigIntSystem.Runtime.InteropServices.JavaScript.JSType.Number . Wywołania zwrotne można przekazać Action/Func<TResult> jako parametry, które są wywoływane jako funkcje możliwe do wywołania.JS Można przekazać odwołania do JS obiektów zarządzanych i i są one marshalowane jako obiekty proxy, utrzymując obiekt aktywny przez granicę do momentu, aż serwer proxy zostanie odśmiecany. Możesz również importować i eksportować metody asynchroniczne z Task wynikiem, które są marshalowane jako JS obietnice. Większość typów marshaled działa w obu kierunkach, jako parametry i jako wartości zwracane, zarówno w metodach importowanych, jak i eksportowanych, które są omówione w sekcji Wywoływanie platformy .NET z języka JavaScript w dalszej części tego artykułu.
W poniższej tabeli przedstawiono obsługiwane mapowania typów.
.NET | JavaScript | Nullable |
Task ➔do Promise |
JSMarshalAs fakultatywny |
Array of |
---|---|---|---|---|---|
Boolean |
Boolean |
Obsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
Byte |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Obsługiwane |
Char |
String |
Obsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
Int16 |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
Int32 |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Obsługiwane |
Int64 |
Number |
Obsługiwane | Obsługiwane | Nieobsługiwane | Nieobsługiwane |
Int64 |
BigInt |
Obsługiwane | Obsługiwane | Nieobsługiwane | Nieobsługiwane |
Single |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
Double |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Obsługiwane |
IntPtr |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
DateTime |
Date |
Obsługiwane | Obsługiwane | Nieobsługiwane | Nieobsługiwane |
DateTimeOffset |
Date |
Obsługiwane | Obsługiwane | Nieobsługiwane | Nieobsługiwane |
Exception |
Error |
Nieobsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
JSObject |
Object |
Nieobsługiwane | Obsługiwane | Obsługiwane | Obsługiwane |
String |
String |
Nieobsługiwane | Obsługiwane | Obsługiwane | Obsługiwane |
Object |
Any |
Nieobsługiwane | Obsługiwane | Nieobsługiwane | Obsługiwane |
Span<Byte> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Span<Int32> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Span<Double> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
ArraySegment<Byte> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
ArraySegment<Int32> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
ArraySegment<Double> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Task |
Promise |
Nieobsługiwane | Nieobsługiwane | Obsługiwane | Nieobsługiwane |
Action |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Action<T1> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Action<T1, T2> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Action<T1, T2, T3> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Func<TResult> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Func<T1, TResult> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Func<T1, T2, TResult> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Func<T1, T2, T3, TResult> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Następujące warunki dotyczą mapowania typów i wartości marshalled:
- Kolumna
Array of
wskazuje, czy typ platformy .NET można rozmieścić jako JSArray
. Przykład: C#int[]
(Int32
) zamapowany na JSArray
sNumber
. - W przypadku przekazywania JS wartości do języka C# z wartością nieprawidłowego typu struktura zgłasza wyjątek w większości przypadków. Struktura nie wykonuje ewidencjonowania typów w czasie kompilacji.JS
JSObject
Task
,Exception
iArraySegment
utwórzGCHandle
i serwer proxy. Usunięcie można wyzwolić w kodzie dewelopera lub zezwolić na późniejsze usunięcie obiektów przez program .NET. Te typy mają znaczne obciążenie związane z wydajnością.Array
: Przeprowadzanie marshalingu tablicy tworzy kopię tablicy na JS platformie lub .NET.MemoryView
MemoryView
jest klasą JS środowiska uruchomieniowego .NET WebAssembly do marshalinguSpan
iArraySegment
.- W przeciwieństwie do marshalingu tablicy, marshaling a
Span
lubArraySegment
nie tworzy kopii pamięci bazowej. MemoryView
Można poprawnie utworzyć wystąpienie tylko przez środowisko uruchomieniowe zestawu WebAssembly platformy .NET. W związku z tym nie można zaimportować JS funkcji jako metody .NET, która ma parametrSpan
lubArraySegment
.MemoryView
element utworzony dla elementuSpan
jest ważny tylko przez czas trwania wywołania międzyoperacyjnego. PonieważSpan
jest przydzielany na stos wywołania wywołania, który nie jest utrwalany po wywołaniu międzyoperamentowym, nie można wyeksportować metody platformy .NET zwracającejSpan
element .MemoryView
utworzony dlaArraySegment
elementu przetrwa po wywołaniu międzyoperacyjnym i jest przydatny do udostępniania buforu. Wywołaniedispose()
elementu utworzonegoMemoryView
dlaArraySegment
serwera proxy powoduje usuwanie serwera proxy i odpina podstawową tablicę .NET. Zalecamy wywołaniedispose()
wtry-finally
bloku dla elementuMemoryView
.
W poniższej tabeli przedstawiono obsługiwane mapowania typów.
.NET | JavaScript | Nullable |
Task ➔do Promise |
JSMarshalAs fakultatywny |
Array of |
---|---|---|---|---|---|
Boolean |
Boolean |
Obsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
Byte |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Obsługiwane |
Char |
String |
Obsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
Int16 |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
Int32 |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Obsługiwane |
Int64 |
Number |
Obsługiwane | Obsługiwane | Nieobsługiwane | Nieobsługiwane |
Int64 |
BigInt |
Obsługiwane | Obsługiwane | Nieobsługiwane | Nieobsługiwane |
Single |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
Double |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Obsługiwane |
IntPtr |
Number |
Obsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
DateTime |
Date |
Obsługiwane | Obsługiwane | Nieobsługiwane | Nieobsługiwane |
DateTimeOffset |
Date |
Obsługiwane | Obsługiwane | Nieobsługiwane | Nieobsługiwane |
Exception |
Error |
Nieobsługiwane | Obsługiwane | Obsługiwane | Nieobsługiwane |
JSObject |
Object |
Nieobsługiwane | Obsługiwane | Obsługiwane | Obsługiwane |
String |
String |
Nieobsługiwane | Obsługiwane | Obsługiwane | Obsługiwane |
Object |
Any |
Nieobsługiwane | Obsługiwane | Nieobsługiwane | Obsługiwane |
Span<Byte> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Span<Int32> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Span<Double> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
ArraySegment<Byte> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
ArraySegment<Int32> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
ArraySegment<Double> |
MemoryView |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Task |
Promise |
Nieobsługiwane | Nieobsługiwane | Obsługiwane | Nieobsługiwane |
Action |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Action<T1> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Action<T1, T2> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Action<T1, T2, T3> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Func<TResult> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Func<T1, TResult> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Func<T1, T2, TResult> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Func<T1, T2, T3, TResult> |
Function |
Nieobsługiwane | Nieobsługiwane | Nieobsługiwane | Nieobsługiwane |
Następujące warunki dotyczą mapowania typów i wartości marshalled:
- Kolumna
Array of
wskazuje, czy typ platformy .NET można rozmieścić jako JSArray
. Przykład: C#int[]
(Int32
) zamapowany na JSArray
sNumber
. - W przypadku przekazywania JS wartości do języka C# z wartością nieprawidłowego typu struktura zgłasza wyjątek w większości przypadków. Struktura nie wykonuje ewidencjonowania typów w czasie kompilacji.JS
JSObject
Task
,Exception
iArraySegment
utwórzGCHandle
i serwer proxy. Usunięcie można wyzwolić w kodzie dewelopera lub zezwolić na późniejsze usunięcie obiektów przez program .NET. Te typy mają znaczne obciążenie związane z wydajnością.Array
: Przeprowadzanie marshalingu tablicy tworzy kopię tablicy na JS platformie lub .NET.MemoryView
MemoryView
jest klasą JS środowiska uruchomieniowego .NET WebAssembly do marshalinguSpan
iArraySegment
.- W przeciwieństwie do marshalingu tablicy, marshaling a
Span
lubArraySegment
nie tworzy kopii pamięci bazowej. MemoryView
Można poprawnie utworzyć wystąpienie tylko przez środowisko uruchomieniowe zestawu WebAssembly platformy .NET. W związku z tym nie można zaimportować JS funkcji jako metody .NET, która ma parametrSpan
lubArraySegment
.MemoryView
element utworzony dla elementuSpan
jest ważny tylko przez czas trwania wywołania międzyoperacyjnego. PonieważSpan
jest przydzielany na stos wywołania wywołania, który nie jest utrwalany po wywołaniu międzyoperamentowym, nie można wyeksportować metody platformy .NET zwracającejSpan
element .MemoryView
utworzony dlaArraySegment
elementu przetrwa po wywołaniu międzyoperacyjnym i jest przydatny do udostępniania buforu. Wywołaniedispose()
elementu utworzonegoMemoryView
dlaArraySegment
serwera proxy powoduje usuwanie serwera proxy i odpina podstawową tablicę .NET. Zalecamy wywołaniedispose()
wtry-finally
bloku dla elementuMemoryView
.
Nazwa modułu w atrybucie [JSImport]
i wywołanie, aby załadować moduł w składniku z elementem JSHost.ImportAsync musi być zgodne i być unikatowe w aplikacji. Podczas tworzenia biblioteki do wdrażania w pakiecie NuGet zalecamy używanie przestrzeni nazw pakietów NuGet jako prefiksu w nazwach modułów. W poniższym przykładzie nazwa modułu odzwierciedla Contoso.InteropServices.JavaScript
pakiet i folder klas międzyoperacyjności komunikatów użytkownika (UserMessages
):
[JSImport("getMessage",
"Contoso.InteropServices.JavaScript.UserMessages.CallJavaScript1")]
Funkcje dostępne w globalnej przestrzeni nazw można importować przy użyciu prefiksu globalThis
w nazwie funkcji i przy użyciu atrybutu bez podawania nazwy modułu [JSImport]
. W poniższym przykładzie console.log
element ma prefiks globalThis
. Zaimportowana funkcja jest wywoływana przez metodę języka C#, która akceptuje komunikat ciągu języka C# Log
(message
) i marshalls ciąg języka C# dla JSString
elementu :console.log
[JSImport("globalThis.console.log")]
internal static partial void Log([JSMarshalAs<JSType.String>] string message);
Wyeksportuj skrypty ze standardowego modułu JavaScript ES6 ze składnikiem lub umieszczone z innymi statycznymi elementami zawartości JavaScript w JS pliku (na przykład wwwroot/js/{FILE NAME}.js
, gdzie JS statyczne zasoby są przechowywane w folderze o nazwie js
w folderze aplikacjiwwwroot
, a {FILE NAME}
symbol zastępczy jest nazwą pliku).
W poniższym przykładzie JS funkcja o nazwie getMessage
jest eksportowana ze s collocated JS pliku, który zwraca komunikat powitalny "Hello from Blazor!" w języku portugalskim:
CallJavaScript1.razor.js
:
export function getMessage() {
return 'Olá do Blazor!';
}
Wywoływanie platformy .NET ze środowiska JavaScript
W tej sekcji wyjaśniono, jak wywoływać metody platformy .NET z programu JS.
CallDotNet1
Następujące wywołania JS składnika, które bezpośrednio współdziałają z elementem DOM w celu renderowania ciągu komunikatu powitalnego:
- Moduł
CallDotNet
JS jest importowany asynchronicznie ze skomponowanego JS pliku dla tego składnika. - Zaimportowana
setMessage
JS funkcja jest wywoływana przezSetWelcomeMessage
funkcję . - Zwrócony komunikat powitalny jest wyświetlany w
setMessage
interfejsie użytkownika za pośrednictwemmessage
pola .
Ważne
W tym przykładzie JS międzyoperacyjności służy do mutowania elementu DOM wyłącznie w celach demonstracyjnych po renderowaniu składnika w programie OnAfterRender
. Zazwyczaj należy mutować JS dom tylko wtedy, gdy obiekt nie wchodzi w interakcję z Blazor. Podejście przedstawione w tej sekcji jest podobne do przypadków, w których biblioteka innej firmy JS jest używana w Razor składniku, w którym składnik wchodzi w interakcję z JS biblioteką za pośrednictwem JS międzyoperacyjności, biblioteka innej firmy JS współdziała z częścią modelu DOM i Blazor nie jest bezpośrednio związana z aktualizacjami MODELU DOM do tej części modelu DOM. Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor JavaScript interoperability (JS interop).
CallDotNet1.razor
:
@page "/call-dotnet-1"
@rendermode InteractiveWebAssembly
@using System.Runtime.InteropServices.JavaScript
<h1>
JS <code>[JSImport]</code>/<code>[JSExport]</code> Interop
(Call .NET Example 1)
</h1>
<p>
<span id="result">.NET method not executed yet</span>
</p>
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JSHost.ImportAsync("CallDotNet1",
"../Components/Pages/CallDotNet1.razor.js");
SetWelcomeMessage();
}
}
}
@page "/call-dotnet-1"
@using System.Runtime.InteropServices.JavaScript
<h1>
JS <code>[JSImport]</code>/<code>[JSExport]</code> Interop
(Call .NET Example 1)
</h1>
<p>
<span id="result">.NET method not executed yet</span>
</p>
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JSHost.ImportAsync("CallDotNet1",
"../Pages/CallDotNet1.razor.js");
SetWelcomeMessage();
}
}
}
Aby wyeksportować metodę .NET, aby można ją było wywołać z JSklasy , użyj atrybutu[JSExport]
.
W poniższym przykładzie:
SetWelcomeMessage
JS wywołuje funkcję o nazwiesetMessage
. Funkcja JS wywołuje program .NET w celu odebrania komunikatu powitalnego zGetMessageFromDotnet
usługi i wyświetli komunikat w interfejsie użytkownika.GetMessageFromDotnet
to metoda .NET z[JSExport]
atrybutem, który zwraca komunikat powitalny "Hello from Blazor!" w języku portugalskim.
CallDotNet1.razor.cs
:
using System.Runtime.InteropServices.JavaScript;
using System.Runtime.Versioning;
namespace BlazorSample.Components.Pages;
[SupportedOSPlatform("browser")]
public partial class CallDotNet1
{
[JSImport("setMessage", "CallDotNet1")]
internal static partial void SetWelcomeMessage();
[JSExport]
internal static string GetMessageFromDotnet()
{
return "Olá do Blazor!";
}
}
Przestrzeń nazw aplikacji dla poprzedniej klasy częściowej CallDotNet1
to BlazorSample
. Przestrzeń nazw składnika to BlazorSample.Components.Pages
. Jeśli używasz poprzedniego składnika w lokalnej aplikacji testowej, zaktualizuj przestrzeń nazw aplikacji, aby odpowiadała aplikacji. Na przykład przestrzeń nazw składnika to ContosoApp.Components.Pages
, jeśli przestrzeń nazw aplikacji to ContosoApp
. Aby uzyskać więcej informacji, zobacz ASP.NET Podstawowe Razor składniki.
W poniższym przykładzie JS funkcja o nazwie setMessage
jest importowana ze sprowadzonego JS pliku.
Metoda setMessage
:
- Wywołania
globalThis.getDotnetRuntime(0)
umożliwiające uwidocznienie wystąpienia środowiska uruchomieniowego platformy .NET zestawu WebAssembly na potrzeby wywoływania wyeksportowanych metod platformy .NET. - Uzyskuje eksporty JS zestawu aplikacji. Nazwa zestawu aplikacji w poniższym przykładzie to
BlazorSample
. - Wywołuje metodę
BlazorSample.Components.Pages.CallDotNet1.GetMessageFromDotnet
z eksportów (exports
). Zwrócona wartość, która jest komunikatem powitalnym, jest przypisana<span>
doCallDotNet1
tekstu składnika. Przestrzeń nazw aplikacji toBlazorSample
, aCallDotNet1
przestrzeń nazw składnika toBlazorSample.Components.Pages
.
CallDotNet1.razor.js
:
export async function setMessage() {
const { getAssemblyExports } = await globalThis.getDotnetRuntime(0);
var exports = await getAssemblyExports("BlazorSample.dll");
document.getElementById("result").innerText =
exports.BlazorSample.Components.Pages.CallDotNet1.GetMessageFromDotnet();
}
using System.Runtime.InteropServices.JavaScript;
using System.Runtime.Versioning;
namespace BlazorSample.Pages;
[SupportedOSPlatform("browser")]
public partial class CallDotNet1
{
[JSImport("setMessage", "CallDotNet1")]
internal static partial void SetWelcomeMessage();
[JSExport]
internal static string GetMessageFromDotnet()
{
return "Olá do Blazor!";
}
}
Przestrzeń nazw aplikacji dla poprzedniej klasy częściowej CallDotNet1
to BlazorSample
. Przestrzeń nazw składnika to BlazorSample.Pages
. Jeśli używasz poprzedniego składnika w lokalnej aplikacji testowej, zaktualizuj przestrzeń nazw aplikacji, aby odpowiadała aplikacji. Na przykład przestrzeń nazw składnika to ContosoApp.Pages
, jeśli przestrzeń nazw aplikacji to ContosoApp
. Aby uzyskać więcej informacji, zobacz ASP.NET Podstawowe Razor składniki.
W poniższym przykładzie JS funkcja o nazwie setMessage
jest importowana ze sprowadzonego JS pliku.
Metoda setMessage
:
- Wywołania
globalThis.getDotnetRuntime(0)
umożliwiające uwidocznienie wystąpienia środowiska uruchomieniowego platformy .NET zestawu WebAssembly na potrzeby wywoływania wyeksportowanych metod platformy .NET. - Uzyskuje eksporty JS zestawu aplikacji. Nazwa zestawu aplikacji w poniższym przykładzie to
BlazorSample
. - Wywołuje metodę
BlazorSample.Pages.CallDotNet1.GetMessageFromDotnet
z eksportów (exports
). Zwrócona wartość, która jest komunikatem powitalnym, jest przypisana<span>
doCallDotNet1
tekstu składnika. Przestrzeń nazw aplikacji toBlazorSample
, aCallDotNet1
przestrzeń nazw składnika toBlazorSample.Pages
.
CallDotNet1.razor.js
:
export async function setMessage() {
const { getAssemblyExports } = await globalThis.getDotnetRuntime(0);
var exports = await getAssemblyExports("BlazorSample.dll");
document.getElementById("result").innerText =
exports.BlazorSample.Pages.CallDotNet1.GetMessageFromDotnet();
}
Uwaga
Wywołanie getAssemblyExports
w celu uzyskania eksportów może wystąpić w inicjatorze języka JavaScript w celu zapewnienia dostępności w aplikacji.
Wiele wywołań importu modułu
Po załadowaniu JS modułu funkcje modułu JS są dostępne dla składników i klas aplikacji, o ile aplikacja jest uruchomiona w oknie przeglądarki lub karcie bez ręcznego ponownego załadowania aplikacji przez użytkownika. JSHost.ImportAsync Można wywołać wiele razy w tym samym module bez znacznej kary za wydajność, gdy:
- Użytkownik odwiedza składnik, który wywołuje JSHost.ImportAsync polecenie importowania modułu, przechodzi z dala od składnika, a następnie wraca do składnika, w którym JSHost.ImportAsync jest wywoływany ponownie w celu zaimportowania tego samego modułu.
- Ten sam moduł jest używany przez różne składniki i ładowany przez JSHost.ImportAsync poszczególne składniki.
Korzystanie z pojedynczego modułu Języka JavaScript między składnikami
Przed wykonaniem wskazówek w tej sekcji przeczytaj sekcje Wywoływanie języka JavaScript z platformy .NET i wywoływanie platformy .NET z poziomu języka JavaScript w tym artykule, które zawierają ogólne wskazówki dotyczące [JSImport]
/[JSExport]
międzyoperacji.
W przykładzie w tej sekcji pokazano, jak używać JS międzyoperacji z udostępnionego JS modułu w aplikacji po stronie klienta. Wskazówki zawarte w tej sekcji nie mają zastosowania do Razor bibliotek klas (RCLS).
Używane są następujące składniki, klasy, metody języka C# i JS funkcje:
Interop
klasa (Interop.cs
): konfiguruje importowanie i eksportowanie JS międzyoperajności za pomocą[JSImport]
atrybutów i[JSExport]
dla modułu o nazwieInterop
.GetWelcomeMessage
: metoda .NET, która wywołuje zaimportowanągetMessage
JS funkcję.SetWelcomeMessage
: metoda .NET, która wywołuje zaimportowanąsetMessage
JS funkcję.GetMessageFromDotnet
: Wyeksportowana metoda języka C#, która zwraca ciąg komunikatu powitalnego po wywołaniu z klasy JS.
wwwroot/js/interop.js
plik: zawiera JS funkcje.getMessage
: zwraca komunikat powitalny, gdy jest wywoływany przez kod języka C# w składniku.setMessage
: wywołuje metodęGetMessageFromDotnet
języka C# i przypisuje zwrócony komunikat powitalny do elementu DOM<span>
.
Program.cs
wywołania JSHost.ImportAsync w celu załadowania modułu z klasywwwroot/js/interop.js
.CallJavaScript2
component (CallJavaScript2.razor
): wywołujeGetWelcomeMessage
i wyświetla zwrócony komunikat powitalny w interfejsie użytkownika składnika.CallDotNet2
component (CallDotNet2.razor
): wywołuje metodęSetWelcomeMessage
.
Interop.cs
:
using System.Runtime.InteropServices.JavaScript;
using System.Runtime.Versioning;
namespace BlazorSample.JavaScriptInterop;
[SupportedOSPlatform("browser")]
public partial class Interop
{
[JSImport("getMessage", "Interop")]
internal static partial string GetWelcomeMessage();
[JSImport("setMessage", "Interop")]
internal static partial void SetWelcomeMessage();
[JSExport]
internal static string GetMessageFromDotnet()
{
return "Olá do Blazor!";
}
}
W poprzednim przykładzie przestrzeń nazw aplikacji to BlazorSample
, a pełną przestrzenią nazw dla klas międzyoperacyjności języka C# jest BlazorSample.JavaScriptInterop
.
wwwroot/js/interop.js
:
export function getMessage() {
return 'Olá do Blazor!';
}
export async function setMessage() {
const { getAssemblyExports } = await globalThis.getDotnetRuntime(0);
var exports = await getAssemblyExports("BlazorSample.dll");
document.getElementById("result").innerText =
exports.BlazorSample.JavaScriptInterop.Interop.GetMessageFromDotnet();
}
System.Runtime.InteropServices.JavaScript Udostępnij przestrzeń nazw w górnej Program.cs
części pliku:
using System.Runtime.InteropServices.JavaScript;
Załaduj moduł w przed Program.cs
WebAssemblyHost.RunAsync wywołaniu:
if (OperatingSystem.IsBrowser())
{
await JSHost.ImportAsync("Interop", "../js/interop.js");
}
CallJavaScript2.razor
:
@page "/call-javascript-2"
@rendermode InteractiveWebAssembly
@using BlazorSample.JavaScriptInterop
<h1>
JS <code>[JSImport]</code>/<code>[JSExport]</code> Interop
(Call JS Example 2)
</h1>
@(message is not null ? message : string.Empty)
@code {
private string? message;
protected override void OnInitialized()
{
message = Interop.GetWelcomeMessage();
}
}
@page "/call-javascript-2"
@using BlazorSample.JavaScriptInterop
<h1>
JS <code>[JSImport]</code>/<code>[JSExport]</code> Interop
(Call JS Example 2)
</h1>
@(message is not null ? message : string.Empty)
@code {
private string? message;
protected override void OnInitialized()
{
message = Interop.GetWelcomeMessage();
}
}
CallDotNet2.razor
:
@page "/call-dotnet-2"
@rendermode InteractiveWebAssembly
@using BlazorSample.JavaScriptInterop
<h1>
JS <code>[JSImport]</code>/<code>[JSExport]</code> Interop
(Call .NET Example 2)
</h1>
<p>
<span id="result">.NET method not executed</span>
</p>
@code {
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
Interop.SetWelcomeMessage();
}
}
}
@page "/call-dotnet-2"
@using BlazorSample.JavaScriptInterop
<h1>
JS <code>[JSImport]</code>/<code>[JSExport]</code> Interop
(Call .NET Example 2)
</h1>
<p>
<span id="result">.NET method not executed</span>
</p>
@code {
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
Interop.SetWelcomeMessage();
}
}
}
Ważne
W tym przykładzie JS międzyoperacyjności służy do mutowania elementu DOM wyłącznie w celach demonstracyjnych po renderowaniu składnika w programie OnAfterRender
. Zazwyczaj należy mutować JS dom tylko wtedy, gdy obiekt nie wchodzi w interakcję z Blazor. Podejście przedstawione w tej sekcji jest podobne do przypadków, w których biblioteka innej firmy JS jest używana w Razor składniku, w którym składnik wchodzi w interakcję z JS biblioteką za pośrednictwem JS międzyoperacyjności, biblioteka innej firmy JS współdziała z częścią modelu DOM i Blazor nie jest bezpośrednio związana z aktualizacjami MODELU DOM do tej części modelu DOM. Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor JavaScript interoperability (JS interop).
Dodatkowe zasoby
- Dokumentacja interfejsu API
- Uruchamianie platformy .NET z poziomu języka JavaScript
dotnet/runtime
W repozytorium GitHub: