Interop JavaScript [JSImport]
/[JSExport]
dengan ASP.NET Core Blazor
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Penting
Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Artikel ini menjelaskan cara berinteraksi dengan JavaScript (JS) di komponen sisi klien menggunakan API interop JavaScript (JS) [JSImport]
/[JSExport]
yang dirilis untuk aplikasi yang mengadopsi .NET 7 atau yang lebih baru.
Blazor menyediakan mekanisme interop sendiri JS berdasarkan IJSRuntime antarmuka. BlazorJS Interop didukung secara seragam di seluruh Blazor mode render dan untuk Blazor Hybrid aplikasi. IJSRuntime juga memungkinkan penulis pustaka untuk membangun JS pustaka interop untuk berbagi di seluruh Blazor ekosistem dan tetap menjadi pendekatan yang direkomendasikan untuk JS interop di Blazor. Lihat artikel berikut:
- Memanggil fungsi JavaScript dari metode .NET di Blazor ASP.NET Core
- Memanggil metode .NET dari fungsi JavaScript di Blazor ASP.NET Core
Artikel ini menjelaskan pendekatan interop alternatif JS khusus untuk komponen sisi klien yang dijalankan di WebAssembly. Pendekatan ini sesuai ketika Anda hanya berharap untuk berjalan di WebAssembly sisi klien. Penulis pustaka dapat menggunakan pendekatan ini untuk mengoptimalkan JS interop dengan memeriksa selama eksekusi kode jika aplikasi berjalan di WebAssembly di browser (OperatingSystem.IsBrowser). Pendekatan yang dijelaskan dalam artikel ini harus digunakan untuk menggantiKAN API interop yang tidak terpakai yang usang JS saat bermigrasi ke .NET 7 atau yang lebih baru.
Catatan
Artikel ini berfokus pada JS interop dalam komponen sisi klien. Untuk panduan tentang memanggil .NET di aplikasi JavaScript, lihat Menjalankan .NET dari JavaScript.
API interop JavaScript usang
Interop yang tidak terencana JS menggunakan IJSUnmarshalledRuntime API usang di ASP.NET Core di .NET 7 atau yang lebih baru. Ikuti panduan dalam artikel ini untuk mengganti API usang.
Prasyarat
Unduh dan instal .NET 7 atau yang lebih baru jika belum diinstal pada sistem atau jika sistem belum menginstal versi terbaru.
Ruang nama
JS API interop yang dijelaskan dalam artikel ini dikontrol oleh atribut di System.Runtime.InteropServices.JavaScript namespace layanan.
Aktifkan blok yang tidak aman
AllowUnsafeBlocks Aktifkan properti dalam file proyek aplikasi, yang mengizinkan generator kode di kompilator Roslyn untuk menggunakan pointer untuk JS interop:
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
Peringatan
JS API interop memerlukan pengaktifan AllowUnsafeBlocks. Berhati-hatilah saat menerapkan kode Anda sendiri yang tidak aman di aplikasi .NET, yang dapat menimbulkan risiko keamanan dan stabilitas. Untuk informasi selengkapnya, lihat Kode tidak aman, jenis penunjuk, dan penunjuk fungsi.
Memanggil JavaScript dari .NET
Bagian ini menjelaskan cara memanggil JS fungsi dari .NET.
Dalam komponen CallJavaScript1
berikut:
- Modul diimpor
CallJavaScript1
secara asinkron dari file yang dikolokasi JS dengan JSHost.ImportAsync. - Fungsi yang diimpor
getMessage
JS dipanggil olehGetWelcomeMessage
. - String pesan selamat datang yang dikembalikan ditampilkan di UI melalui
message
bidang .
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();
}
}
Catatan
Sertakan kode cek masuk bersyarat dengan OperatingSystem.IsBrowser untuk memastikan bahwa JS interop hanya dipanggil oleh komponen yang dirender pada klien. Ini penting untuk pustaka/paket NuGet yang menargetkan komponen sisi server, yang tidak dapat menjalankan kode yang disediakan oleh API interop ini JS .
Untuk mengimpor JS fungsi untuk memanggilnya dari C#, gunakan [JSImport]
atribut pada tanda tangan metode C# yang cocok dengan JS tanda tangan fungsi. Parameter pertama untuk [JSImport]
atribut adalah nama fungsi yang akan diimpor JS , dan parameter kedua adalah nama JS modul.
Dalam contoh berikut, getMessage
adalah JS fungsi yang mengembalikan string
untuk modul bernama CallJavaScript1
. Tanda tangan metode C#cocok: Tidak ada parameter yang diteruskan ke JS fungsi, dan JS fungsi mengembalikan string
. Fungsi JS ini dipanggil oleh GetWelcomeMessage
dalam kode 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();
}
Namespace aplikasi untuk kelas parsial sebelumnya CallJavaScript1
adalah BlazorSample
. Namespace layanan komponen adalah BlazorSample.Components.Pages
. Jika menggunakan komponen sebelumnya di aplikasi pengujian lokal, perbarui namespace agar sesuai dengan aplikasi. Misalnya, namespace layanan adalah ContosoApp.Components.Pages
jika namespace aplikasi adalah ContosoApp
. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.
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();
}
Namespace aplikasi untuk kelas parsial sebelumnya CallJavaScript1
adalah BlazorSample
. Namespace layanan komponen adalah BlazorSample.Pages
. Jika menggunakan komponen sebelumnya di aplikasi pengujian lokal, perbarui namespace agar sesuai dengan aplikasi. Misalnya, namespace layanan adalah ContosoApp.Pages
jika namespace aplikasi adalah ContosoApp
. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.
Dalam tanda tangan metode yang diimpor, Anda dapat menggunakan jenis .NET untuk parameter dan mengembalikan nilai, yang dinamai secara otomatis oleh runtime. Gunakan JSMarshalAsAttribute<T> untuk mengontrol bagaimana parameter metode yang diimpor di-marshalled. Misalnya, Anda dapat memilih untuk marshal a long
sebagai System.Runtime.InteropServices.JavaScript.JSType.Number atau System.Runtime.InteropServices.JavaScript.JSType.BigInt. Anda dapat meneruskan Action/Func<TResult> panggilan balik sebagai parameter, yang dinamai sebagai fungsi yang dapat JS dipanggil. Anda dapat meneruskan JS referensi objek dan terkelola, dan dinamai sebagai objek proksi, menjaga objek tetap hidup di seluruh batas sampai proksi dikumpulkan sampah. Anda juga dapat mengimpor dan mengekspor metode asinkron dengan Task hasil, yang dinamai sebagai JS janji. Sebagian besar jenis marshalled bekerja di kedua arah, sebagai parameter dan sebagai nilai pengembalian, pada metode yang diimpor dan diekspor, yang tercakup di bagian Panggil .NET dari JavaScript nanti di artikel ini.
Tabel berikut menunjukkan pemetaan jenis yang didukung.
.NET | JavaScript | Nullable |
Task ➔kePromise |
JSMarshalAs fakultatif |
Array of |
---|---|---|---|---|---|
Boolean |
Boolean |
Didukung | Didukung | Didukung | Tidak didukung |
Byte |
Number |
Didukung | Didukung | Didukung | Didukung |
Char |
String |
Didukung | Didukung | Didukung | Tidak didukung |
Int16 |
Number |
Didukung | Didukung | Didukung | Tidak didukung |
Int32 |
Number |
Didukung | Didukung | Didukung | Didukung |
Int64 |
Number |
Didukung | Didukung | Tidak didukung | Tidak didukung |
Int64 |
BigInt |
Didukung | Didukung | Tidak didukung | Tidak didukung |
Single |
Number |
Didukung | Didukung | Didukung | Tidak didukung |
Double |
Number |
Didukung | Didukung | Didukung | Didukung |
IntPtr |
Number |
Didukung | Didukung | Didukung | Tidak didukung |
DateTime |
Date |
Didukung | Didukung | Tidak didukung | Tidak didukung |
DateTimeOffset |
Date |
Didukung | Didukung | Tidak didukung | Tidak didukung |
Exception |
Error |
Tidak didukung | Didukung | Didukung | Tidak didukung |
JSObject |
Object |
Tidak didukung | Didukung | Didukung | Didukung |
String |
String |
Tidak didukung | Didukung | Didukung | Didukung |
Object |
Any |
Tidak didukung | Didukung | Tidak didukung | Didukung |
Span<Byte> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Span<Int32> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Span<Double> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
ArraySegment<Byte> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
ArraySegment<Int32> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
ArraySegment<Double> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Task |
Promise |
Tidak didukung | Tidak didukung | Didukung | Tidak didukung |
Action |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Action<T1> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Action<T1, T2> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Action<T1, T2, T3> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Func<TResult> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Func<T1, TResult> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Func<T1, T2, TResult> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Func<T1, T2, T3, TResult> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Kondisi berikut berlaku untuk mengetik nilai pemetaan dan marshalled:
- Kolom
Array of
menunjukkan apakah jenis .NET dapat dinamai sebagai JSArray
. Contoh: C#int[]
(Int32
) dipetakan ke JSArray
sNumber
. - Saat meneruskan JS nilai ke C# dengan nilai jenis yang salah, kerangka kerja melemparkan pengecualian dalam banyak kasus. Kerangka kerja tidak melakukan pemeriksaan jenis waktu kompilasi di JS.
JSObject
,Exception
,Task
danArraySegment
buatGCHandle
dan proksi. Anda dapat memicu pembuangan dalam kode pengembang atau mengizinkan pengumpulan sampah .NET (GC) untuk membuang objek nanti. Jenis-jenis ini membawa overhead performa yang signifikan.Array
: Marshaling array membuat salinan array di JS atau .NET.MemoryView
MemoryView
adalah JS kelas untuk runtime .NET WebAssembly ke marshalSpan
danArraySegment
.- Tidak seperti marshaling array, marshaling
Span
atauArraySegment
tidak membuat salinan memori yang mendasar. MemoryView
hanya dapat dibuat dengan benar oleh runtime .NET WebAssembly. Oleh karena itu, tidak dimungkinkan untuk mengimpor JS fungsi sebagai metode .NET yang memiliki parameterSpan
atauArraySegment
.MemoryView
dibuat untukSpan
hanya valid selama durasi panggilan interop. SepertiSpan
yang dialokasikan pada tumpukan panggilan, yang tidak bertahan setelah panggilan interop, tidak dimungkinkan untuk mengekspor metode .NET yang mengembalikanSpan
.MemoryView
dibuat untukArraySegment
bertahan hidup setelah panggilan interop dan berguna untuk berbagi buffer. Memanggildispose()
pada yangMemoryView
ArraySegment
dibuat untuk membuang proksi dan melepaskan array .NET yang mendasar. Sebaiknya panggildispose()
ditry-finally
blok untukMemoryView
.
Tabel berikut menunjukkan pemetaan jenis yang didukung.
.NET | JavaScript | Nullable |
Task ➔kePromise |
JSMarshalAs fakultatif |
Array of |
---|---|---|---|---|---|
Boolean |
Boolean |
Didukung | Didukung | Didukung | Tidak didukung |
Byte |
Number |
Didukung | Didukung | Didukung | Didukung |
Char |
String |
Didukung | Didukung | Didukung | Tidak didukung |
Int16 |
Number |
Didukung | Didukung | Didukung | Tidak didukung |
Int32 |
Number |
Didukung | Didukung | Didukung | Didukung |
Int64 |
Number |
Didukung | Didukung | Tidak didukung | Tidak didukung |
Int64 |
BigInt |
Didukung | Didukung | Tidak didukung | Tidak didukung |
Single |
Number |
Didukung | Didukung | Didukung | Tidak didukung |
Double |
Number |
Didukung | Didukung | Didukung | Didukung |
IntPtr |
Number |
Didukung | Didukung | Didukung | Tidak didukung |
DateTime |
Date |
Didukung | Didukung | Tidak didukung | Tidak didukung |
DateTimeOffset |
Date |
Didukung | Didukung | Tidak didukung | Tidak didukung |
Exception |
Error |
Tidak didukung | Didukung | Didukung | Tidak didukung |
JSObject |
Object |
Tidak didukung | Didukung | Didukung | Didukung |
String |
String |
Tidak didukung | Didukung | Didukung | Didukung |
Object |
Any |
Tidak didukung | Didukung | Tidak didukung | Didukung |
Span<Byte> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Span<Int32> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Span<Double> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
ArraySegment<Byte> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
ArraySegment<Int32> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
ArraySegment<Double> |
MemoryView |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Task |
Promise |
Tidak didukung | Tidak didukung | Didukung | Tidak didukung |
Action |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Action<T1> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Action<T1, T2> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Action<T1, T2, T3> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Func<TResult> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Func<T1, TResult> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Func<T1, T2, TResult> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Func<T1, T2, T3, TResult> |
Function |
Tidak didukung | Tidak didukung | Tidak didukung | Tidak didukung |
Kondisi berikut berlaku untuk mengetik nilai pemetaan dan marshalled:
- Kolom
Array of
menunjukkan apakah jenis .NET dapat dinamai sebagai JSArray
. Contoh: C#int[]
(Int32
) dipetakan ke JSArray
sNumber
. - Saat meneruskan JS nilai ke C# dengan nilai jenis yang salah, kerangka kerja melemparkan pengecualian dalam banyak kasus. Kerangka kerja tidak melakukan pemeriksaan jenis waktu kompilasi di JS.
JSObject
,Exception
,Task
danArraySegment
buatGCHandle
dan proksi. Anda dapat memicu pembuangan dalam kode pengembang atau mengizinkan pengumpulan sampah .NET (GC) untuk membuang objek nanti. Jenis-jenis ini membawa overhead performa yang signifikan.Array
: Marshaling array membuat salinan array di JS atau .NET.MemoryView
MemoryView
adalah JS kelas untuk runtime .NET WebAssembly ke marshalSpan
danArraySegment
.- Tidak seperti marshaling array, marshaling
Span
atauArraySegment
tidak membuat salinan memori yang mendasar. MemoryView
hanya dapat dibuat dengan benar oleh runtime .NET WebAssembly. Oleh karena itu, tidak dimungkinkan untuk mengimpor JS fungsi sebagai metode .NET yang memiliki parameterSpan
atauArraySegment
.MemoryView
dibuat untukSpan
hanya valid selama durasi panggilan interop. SepertiSpan
yang dialokasikan pada tumpukan panggilan, yang tidak bertahan setelah panggilan interop, tidak dimungkinkan untuk mengekspor metode .NET yang mengembalikanSpan
.MemoryView
dibuat untukArraySegment
bertahan hidup setelah panggilan interop dan berguna untuk berbagi buffer. Memanggildispose()
pada yangMemoryView
ArraySegment
dibuat untuk membuang proksi dan melepaskan array .NET yang mendasar. Sebaiknya panggildispose()
ditry-finally
blok untukMemoryView
.
Nama modul dalam [JSImport]
atribut dan panggilan untuk memuat modul dalam komponen harus JSHost.ImportAsync cocok dan unik di aplikasi. Saat menulis pustaka untuk penyebaran dalam paket NuGet, sebaiknya gunakan namespace paket NuGet sebagai awalan dalam nama modul. Dalam contoh berikut, nama modul mencerminkan Contoso.InteropServices.JavaScript
paket dan folder kelas interop pesan pengguna (UserMessages
):
[JSImport("getMessage",
"Contoso.InteropServices.JavaScript.UserMessages.CallJavaScript1")]
Fungsi yang dapat diakses pada namespace global dapat diimpor dengan menggunakan globalThis
awalan dalam nama fungsi dan dengan menggunakan [JSImport]
atribut tanpa memberikan nama modul. Dalam contoh berikut, console.log
diawali dengan globalThis
. Fungsi yang diimpor dipanggil oleh metode C# Log
, yang menerima pesan string C# (message
) dan marshalls string C# ke JSString
untuk console.log
:
[JSImport("globalThis.console.log")]
internal static partial void Log([JSMarshalAs<JSType.String>] string message);
Ekspor skrip dari modul JavaScript ES6 standar baik dikolokasikan dengan komponen atau ditempatkan dengan aset statis JavaScript lainnya dalam JS file (misalnya, wwwroot/js/{FILE NAME}.js
, di mana JS aset statis dipertahankan dalam folder bernama js
di folder aplikasi wwwroot
dan {FILE NAME}
tempat penampung adalah nama file).
Dalam contoh berikut, JS fungsi bernama getMessage
diekspor dari file yang dikolokasi JS yang mengembalikan pesan selamat datang, "Halo dari Blazor!" dalam bahasa Portugis:
CallJavaScript1.razor.js
:
export function getMessage() {
return 'Olá do Blazor!';
}
Memanggil .NET dari JavaScript
Bagian ini menjelaskan cara memanggil metode .NET dari JS.
Komponen berikut CallDotNet1
memanggil JS yang langsung berinteraksi dengan DOM untuk merender string pesan selamat datang:
- Modul diimporJS
CallDotNet
secara asinkron dari file yang dikolokasi JS untuk komponen ini. - Fungsi yang diimpor
setMessage
JS dipanggil olehSetWelcomeMessage
. - Pesan selamat datang yang dikembalikan ditampilkan oleh
setMessage
di UI melaluimessage
bidang .
Penting
Dalam contoh bagian ini, JS interop digunakan untuk memutasi elemen DOM murni untuk tujuan demonstrasi setelah komponen dirender dalam OnAfterRender
. Biasanya, Anda hanya boleh membisukan DOM dengan JS ketika objek tidak berinteraksi dengan Blazor. Pendekatan yang ditunjukkan di bagian ini mirip dengan kasus di mana pustaka pihak JS ketiga digunakan dalam Razor komponen, di mana komponen berinteraksi dengan JS pustaka melalui JS interop, pustaka pihak JS ketiga berinteraksi dengan bagian dari DOM, dan Blazor tidak terlibat langsung dengan pembaruan DOM ke bagian DOM tersebut. Untuk informasi selengkapnya, lihat ASP.NET Blazor interoperabilitas Core JavaScript (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();
}
}
}
Untuk mengekspor metode .NET sehingga dapat dipanggil dari JS, gunakan [JSExport]
atribut .
Dalam contoh berikut:
SetWelcomeMessage
JS memanggil fungsi bernamasetMessage
. Fungsi memanggil JS ke .NET untuk menerima pesan selamat datang dariGetMessageFromDotnet
dan menampilkan pesan di UI.GetMessageFromDotnet
adalah metode .NET dengan[JSExport]
atribut yang mengembalikan pesan selamat datang, "Halo dari Blazor!" dalam bahasa Portugis.
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!";
}
}
Namespace aplikasi untuk kelas parsial sebelumnya CallDotNet1
adalah BlazorSample
. Namespace layanan komponen adalah BlazorSample.Components.Pages
. Jika menggunakan komponen sebelumnya di aplikasi pengujian lokal, perbarui namespace aplikasi agar sesuai dengan aplikasi. Misalnya, namespace komponen adalah ContosoApp.Components.Pages
jika namespace aplikasi adalah ContosoApp
. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.
Dalam contoh berikut, JS fungsi bernama setMessage
diimpor dari file yang dikolokasi JS .
Metode setMessage
:
- Panggilan untuk mengekspos instans
globalThis.getDotnetRuntime(0)
runtime WebAssembly .NET untuk memanggil metode .NET yang diekspor. - Mendapatkan ekspor perakitan JS aplikasi. Nama rakitan aplikasi dalam contoh berikut adalah
BlazorSample
. BlazorSample.Components.Pages.CallDotNet1.GetMessageFromDotnet
Memanggil metode dari ekspor (exports
). Nilai yang dikembalikan, yang merupakan pesan selamat datang, ditetapkan keCallDotNet1
teks komponen<span>
. Namespace aplikasi adalahBlazorSample
, danCallDotNet1
namespace komponennya adalahBlazorSample.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!";
}
}
Namespace aplikasi untuk kelas parsial sebelumnya CallDotNet1
adalah BlazorSample
. Namespace layanan komponen adalah BlazorSample.Pages
. Jika menggunakan komponen sebelumnya di aplikasi pengujian lokal, perbarui namespace aplikasi agar sesuai dengan aplikasi. Misalnya, namespace komponen adalah ContosoApp.Pages
jika namespace aplikasi adalah ContosoApp
. Untuk informasi selengkapnya, lihat komponen ASP.NET CoreRazor.
Dalam contoh berikut, JS fungsi bernama setMessage
diimpor dari file yang dikolokasi JS .
Metode setMessage
:
- Panggilan untuk mengekspos instans
globalThis.getDotnetRuntime(0)
runtime WebAssembly .NET untuk memanggil metode .NET yang diekspor. - Mendapatkan ekspor perakitan JS aplikasi. Nama rakitan aplikasi dalam contoh berikut adalah
BlazorSample
. BlazorSample.Pages.CallDotNet1.GetMessageFromDotnet
Memanggil metode dari ekspor (exports
). Nilai yang dikembalikan, yang merupakan pesan selamat datang, ditetapkan keCallDotNet1
teks komponen<span>
. Namespace aplikasi adalahBlazorSample
, danCallDotNet1
namespace komponennya adalahBlazorSample.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();
}
Catatan
Panggilan getAssemblyExports
untuk mendapatkan ekspor dapat terjadi di penginisialisasi JavaScript untuk ketersediaan di seluruh aplikasi.
Beberapa panggilan impor modul
JS Setelah modul dimuat, fungsi modul JS tersedia untuk komponen dan kelas aplikasi selama aplikasi berjalan di jendela atau tab browser tanpa pengguna memuat ulang aplikasi secara manual. JSHost.ImportAsync dapat dipanggil beberapa kali pada modul yang sama tanpa penalti performa yang signifikan ketika:
- Pengguna mengunjungi komponen yang memanggil JSHost.ImportAsync untuk mengimpor modul, menavigasi jauh dari komponen, lalu kembali ke komponen tempat JSHost.ImportAsync dipanggil lagi untuk impor modul yang sama.
- Modul yang sama digunakan oleh komponen yang berbeda dan dimuat oleh JSHost.ImportAsync di setiap komponen.
Penggunaan modul JavaScript tunggal di seluruh komponen
Sebelum mengikuti panduan di bagian ini, baca bagian Panggil JavaScript dari .NET dan Panggil .NET dari JavaScript di artikel ini, yang memberikan panduan umum tentang [JSImport]
/[JSExport]
interop.
Contoh di bagian ini menunjukkan cara menggunakan JS interop dari modul bersama JS di aplikasi sisi klien. Panduan di bagian ini tidak berlaku untuk Razor pustaka kelas (RCL).
Komponen, kelas, metode C#, dan JS fungsi berikut digunakan:
Interop
class (Interop.cs
): Menyiapkan interop impor dan ekspor JS dengan[JSImport]
atribut dan[JSExport]
untuk modul bernamaInterop
.GetWelcomeMessage
: Metode .NET yang memanggil fungsi yang diimporgetMessage
JS .SetWelcomeMessage
: Metode .NET yang memanggil fungsi yang diimporsetMessage
JS .GetMessageFromDotnet
: Metode C# yang diekspor yang mengembalikan string pesan selamat datang saat dipanggil dari JS.
wwwroot/js/interop.js
file: Berisi JS fungsi.getMessage
: Mengembalikan pesan selamat datang saat dipanggil oleh kode C# dalam komponen.setMessage
: MemanggilGetMessageFromDotnet
metode C# dan menetapkan pesan selamat datang yang dikembalikan ke elemen DOM<span>
.
Program.cs
JSHost.ImportAsync panggilan untuk memuat modul dariwwwroot/js/interop.js
.CallJavaScript2
komponen (CallJavaScript2.razor
): MemanggilGetWelcomeMessage
dan menampilkan pesan selamat datang yang dikembalikan di UI komponen.CallDotNet2
komponen (CallDotNet2.razor
): MemanggilSetWelcomeMessage
.
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!";
}
}
Dalam contoh sebelumnya, namespace aplikasi adalah BlazorSample
, dan namespace lengkap untuk kelas interop C# adalah 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();
}
Jadikan System.Runtime.InteropServices.JavaScript namespace tersedia di bagian Program.cs
atas file:
using System.Runtime.InteropServices.JavaScript;
Muat modul sebelumnya Program.cs
WebAssemblyHost.RunAsync dipanggil:
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();
}
}
}
Penting
Dalam contoh bagian ini, JS interop digunakan untuk memutasi elemen DOM murni untuk tujuan demonstrasi setelah komponen dirender dalam OnAfterRender
. Biasanya, Anda hanya boleh membisukan DOM dengan JS ketika objek tidak berinteraksi dengan Blazor. Pendekatan yang ditunjukkan di bagian ini mirip dengan kasus di mana pustaka pihak JS ketiga digunakan dalam Razor komponen, di mana komponen berinteraksi dengan JS pustaka melalui JS interop, pustaka pihak JS ketiga berinteraksi dengan bagian dari DOM, dan Blazor tidak terlibat langsung dengan pembaruan DOM ke bagian DOM tersebut. Untuk informasi selengkapnya, lihat ASP.NET Blazor interoperabilitas Core JavaScript (JS interop).
Sumber Daya Tambahan:
- Dokumentasi API
- Jalankan .NET dari JavaScript
dotnet/runtime
Di repositori GitHub:
ASP.NET Core
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk