Взаимодействие JavaScript [JSImport]
/[JSExport]
с ASP.NET Core Blazor
Примечание.
Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 8 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в статье о политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 8 этой статьи.
Внимание
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В текущем выпуске см . версию .NET 8 этой статьи.
В этой статье объясняется, как взаимодействовать с JavaScript () в клиентских компонентах с помощью API взаимодействия JavaScript (JSJS), [JSImport]
/[JSExport]
выпущенного для приложений, использующих .NET 7 или более поздней версии.
Blazor предоставляет собственный JS механизм взаимодействия на IJSRuntime основе интерфейса. BlazorJS Взаимодействие поддерживается Blazor в режимах отрисовки и для Blazor Hybrid приложений. IJSRuntimeтакже позволяет авторам библиотек создавать JS библиотеки взаимодействия для совместного использования в экосистеме Blazor и остается рекомендуемым подходом для JS взаимодействия.Blazor См. следующие статьи:
- Вызов функций JavaScript из методов .NET в ASP.NET Core Blazor
- Вызов методов .NET из функций JavaScript в Blazor ASP.NET Core
В этой статье описывается альтернативный JS подход взаимодействия, характерный для клиентских компонентов, выполняемых в WebAssembly. Эти подходы подходы подходят только для выполнения только на стороне клиента WebAssembly. Авторы библиотеки могут использовать эти подходы для оптимизации JS взаимодействия, проверяя во время выполнения кода, если приложение работает в WebAssembly в браузере (OperatingSystem.IsBrowser). Подходы, описанные в этой статье, следует использовать для замены устаревшего немаршилированного JS API взаимодействия при миграции на .NET 7 или более поздней версии.
Примечание.
В этой статье основное внимание уделяется JS взаимодействиям в клиентских компонентах. Рекомендации по вызову .NET в приложениях JavaScript см. в статье Запуск .NET из JavaScript.
Устаревший API взаимодействия JavaScript
Немарсхоллированные JS взаимодействия с ПОМОЩЬЮ IJSUnmarshalledRuntime API устарели в ASP.NET Core в .NET 7 или более поздней версии. Следуйте инструкциям из этой статьи, чтобы заменить устаревший API.
Необходимые компоненты
Скачайте и установите .NET 7 или более поздней версии , если она еще не установлена в системе или если у системы нет последней версии.
Пространство имен
API взаимодействия (JSHost.ImportAsync), описанный JS в этой статье, управляется атрибутами в System.Runtime.InteropServices.JavaScript пространстве имен.
Включение небезопасных блоков
AllowUnsafeBlocks Включите свойство в файле проекта приложения, который позволяет генератору кода в компиляторе Roslyn использовать указатели для JS взаимодействия:
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
Предупреждение
JS API взаимодействия требует включенияAllowUnsafeBlocks. Будьте осторожны при реализации собственного небезопасного кода в приложениях .NET, что может привести к рискам безопасности и стабильности. Дополнительные сведения см. в разделе "Небезопасный код", "типы указателей" и указатели функций.
Razor Сортировка JS библиотеки классов (RCL) не поддерживается
Как правило, JS поддержка взаимодействия на основе JS расположения (расположение JavaScript в приложениях ASP.NET CoreBlazor) также представлена для [JSImport]
/[JSExport]
взаимодействия, описанного в этой статье.IJSRuntime Единственная функция неподдерживаемого JS расположения — для сортировки JS в библиотеке Razor классов (RCL).
Вместо использования сортировки JS в RCL поместите JS файл в папку RCL и сослаться на него с помощью обычного пути для статических ресурсов RCL wwwroot
:
_content/{PACKAGE ID}/{PATH}/{FILE NAME}.js
- Заполнитель
{PACKAGE ID}
— это идентификатор пакета RCL (или имя библиотеки для библиотеки классов). - Заполнитель
{PATH}
— это путь к файлу. - Заполнитель
{FILE NAME}
— это имя файла.
Хотя сортировка JS в RCL не поддерживается[JSExport]
[JSImport]
/взаимодействием, вы можете упорядочить JS файлы, выполнив любой из следующих подходов:
- Присвойте файлу JS имя того же компонента, который JS используется. Для компонента в именованном RCL
CallJavaScriptFromLib
(CallJavaScriptFromLib.razor
) назовите файлCallJavaScriptFromLib.js
в папкеwwwroot
. - Поместите файлы, относящиеся к компонентуJS, в
Components
папку RCLwwwroot
и используйте "Components
" в пути к файлу:_content/{PACKAGE ID}/Components/CallJavaScriptFromLib.js
Вызов JavaScript из .NET
В этом разделе объясняется, как вызывать JS функции из .NET.
Следующий компонент CallJavaScript1
:
- Модуль
CallJavaScript1
импортируется асинхронно из файла с сортировкой JS JSHost.ImportAsync. - Импортированная
getMessage
JS функция вызываетсяGetWelcomeMessage
. - Возвращаемая строка приветственного сообщения отображается в пользовательском интерфейсе
message
через поле.
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();
}
}
Примечание.
Включите условный контрольный код, OperatingSystem.IsBrowser чтобы убедиться, что JS взаимодействие вызывается только компонентом, отображаемым на клиенте. Это важно для библиотек и пакетов NuGet, предназначенных для компонентов на стороне сервера, которые не могут выполнять код, предоставленный этим JS API взаимодействия.
Чтобы импортировать JS функцию для вызова из C#, используйте [JSImport]
атрибут в сигнатуре метода C#, которая соответствует JS сигнатуре функции. Первым параметром атрибута [JSImport]
является имя функции для JS импорта, а второй параметр — имя JS модуля.
В следующем примере — это функция, getMessage
которая возвращает string
для модуля с именемCallJavaScript1
.JS Сигнатура метода C# совпадает: параметры не передаются JS в функцию, а JS функция возвращает значение string
. Функция JS вызывается в коде GetWelcomeMessage
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();
}
Пространство имен приложения для предыдущего CallJavaScript1
частичного класса BlazorSample
. Пространство имен компонента .BlazorSample.Components.Pages
При использовании предыдущего компонента в локальном тестовом приложении обновите пространство имен, чтобы оно соответствовало приложению. Например, пространство имен — это ContosoApp.Components.Pages
пространство ContosoApp
имен приложения. Дополнительные сведения см. в статье Компоненты Razor ASP.NET Core.
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();
}
Пространство имен приложения для предыдущего CallJavaScript1
частичного класса BlazorSample
. Пространство имен компонента .BlazorSample.Pages
При использовании предыдущего компонента в локальном тестовом приложении обновите пространство имен, чтобы оно соответствовало приложению. Например, пространство имен — это ContosoApp.Pages
пространство ContosoApp
имен приложения. Дополнительные сведения см. в статье Компоненты Razor ASP.NET Core.
В импортированной сигнатуре метода можно использовать типы .NET для параметров и возвращаемых значений, которые автоматически маршалируются средой выполнения. Используется JSMarshalAsAttribute<T> для управления маршаллами импортированных параметров метода. Например, можно выбрать маршалировать как long
System.Runtime.InteropServices.JavaScript.JSType.Number или System.Runtime.InteropServices.JavaScript.JSType.BigInt. Обратные вызовы можно передавать Action/Func<TResult> в качестве параметров, которые маршалируются как вызываемые JS функции. Вы можете передавать JS как ссылки на управляемые объекты, так и маршалируются как прокси-объекты, сохраняя объект в живых по границе, пока прокси-сервер не собирает мусор. Вы также можете импортировать и экспортировать асинхронные методы с результатом Task , которые маршалируются в качестве JS обещаний. Большинство маршаллированных типов работают в обоих направлениях в качестве параметров и возвращаемых значений в импортированных и экспортированных методах, которые рассматриваются в разделе Call .NET из JavaScript далее в этой статье.
В следующей таблице указаны поддерживаемые сопоставления типов.
.NET | JavaScript | Nullable |
Task ➔Кому Promise |
JSMarshalAs необязательный |
Array of |
---|---|---|---|---|---|
Boolean |
Boolean |
Поддерживается | Поддерживается | Поддерживается | Не поддерживаются |
Byte |
Number |
Поддерживается | Поддерживается | Поддерживается | Поддерживается |
Char |
String |
Поддерживается | Поддерживается | Поддерживается | Не поддерживаются |
Int16 |
Number |
Поддерживается | Поддерживается | Поддерживается | Не поддерживаются |
Int32 |
Number |
Поддерживается | Поддерживается | Поддерживается | Поддерживается |
Int64 |
Number |
Поддерживается | Поддерживается | Не поддерживаются | Не поддерживаются |
Int64 |
BigInt |
Поддерживается | Поддерживается | Не поддерживаются | Не поддерживаются |
Single |
Number |
Поддерживается | Поддерживается | Поддерживается | Не поддерживаются |
Double |
Number |
Поддерживается | Поддерживается | Поддерживается | Поддерживается |
IntPtr |
Number |
Поддерживается | Поддерживается | Поддерживается | Не поддерживаются |
DateTime |
Date |
Поддерживается | Поддерживается | Не поддерживаются | Не поддерживаются |
DateTimeOffset |
Date |
Поддерживается | Поддерживается | Не поддерживаются | Не поддерживаются |
Exception |
Error |
Не поддерживаются | Поддерживается | Поддерживается | Не поддерживаются |
JSObject |
Object |
Не поддерживаются | Поддерживается | Поддерживается | Поддерживается |
String |
String |
Не поддерживаются | Поддерживается | Поддерживается | Поддерживается |
Object |
Any |
Не поддерживаются | Поддерживается | Не поддерживаются | Поддерживается |
Span<Byte> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Span<Int32> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Span<Double> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
ArraySegment<Byte> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
ArraySegment<Int32> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
ArraySegment<Double> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Task |
Promise |
Не поддерживаются | Не поддерживаются | Поддерживается | Не поддерживаются |
Action |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Action<T1> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Action<T1, T2> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Action<T1, T2, T3> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Func<TResult> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Func<T1, TResult> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Func<T1, T2, TResult> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Func<T1, T2, T3, TResult> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Следующие условия применяются к сопоставлению типов и маршализированным значениям:
- Столбец
Array of
указывает, можно ли маршалировать тип .NET в виде JSArray
. Пример: C#int[]
(Int32
) сопоставлен с JSArray
Number
s. - При передаче JS значения в C# со значением неправильного типа платформа создает исключение в большинстве случаев. Платформа не выполняет проверку JSтипа во время компиляции.
JSObject
Task
,Exception
и созданиеGCHandle
иArraySegment
прокси-сервер. Вы можете активировать удаление в коде разработчика или разрешить сборку мусора .NET (GC) удалять объекты позже. Эти типы несут значительные затраты на производительность.Array
: маршалинг массива создает копию массива в JS или .NET.MemoryView
MemoryView
JS— это класс среды выполнения .NET WebAssembly для маршалированияSpan
иArraySegment
.- В отличие от маршалинга массива, маршалинг или
Span
ArraySegment
не создает копию базовой памяти. MemoryView
может быть правильно создано средой выполнения .NET WebAssembly. Поэтому невозможно импортировать JS функцию как метод .NET, имеющий параметрSpan
илиArraySegment
.MemoryView
создается только дляSpan
срока вызова взаимодействия. КакSpan
и в стеке вызовов, который не сохраняется после вызова взаимодействия, невозможно экспортировать метод .NET, который возвращаетSpan
.MemoryView
создано дляArraySegment
выживания после вызова взаимодействия и полезно для совместного использования буфера. Вызовdispose()
созданногоMemoryView
ArraySegment
для удаления прокси-сервера и открепляет базовый массив .NET. Рекомендуется вызыватьdispose()
блокtry-finally
дляMemoryView
.
В следующей таблице указаны поддерживаемые сопоставления типов.
.NET | JavaScript | Nullable |
Task ➔Кому Promise |
JSMarshalAs необязательный |
Array of |
---|---|---|---|---|---|
Boolean |
Boolean |
Поддерживается | Поддерживается | Поддерживается | Не поддерживаются |
Byte |
Number |
Поддерживается | Поддерживается | Поддерживается | Поддерживается |
Char |
String |
Поддерживается | Поддерживается | Поддерживается | Не поддерживаются |
Int16 |
Number |
Поддерживается | Поддерживается | Поддерживается | Не поддерживаются |
Int32 |
Number |
Поддерживается | Поддерживается | Поддерживается | Поддерживается |
Int64 |
Number |
Поддерживается | Поддерживается | Не поддерживаются | Не поддерживаются |
Int64 |
BigInt |
Поддерживается | Поддерживается | Не поддерживаются | Не поддерживаются |
Single |
Number |
Поддерживается | Поддерживается | Поддерживается | Не поддерживаются |
Double |
Number |
Поддерживается | Поддерживается | Поддерживается | Поддерживается |
IntPtr |
Number |
Поддерживается | Поддерживается | Поддерживается | Не поддерживаются |
DateTime |
Date |
Поддерживается | Поддерживается | Не поддерживаются | Не поддерживаются |
DateTimeOffset |
Date |
Поддерживается | Поддерживается | Не поддерживаются | Не поддерживаются |
Exception |
Error |
Не поддерживаются | Поддерживается | Поддерживается | Не поддерживаются |
JSObject |
Object |
Не поддерживаются | Поддерживается | Поддерживается | Поддерживается |
String |
String |
Не поддерживаются | Поддерживается | Поддерживается | Поддерживается |
Object |
Any |
Не поддерживаются | Поддерживается | Не поддерживаются | Поддерживается |
Span<Byte> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Span<Int32> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Span<Double> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
ArraySegment<Byte> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
ArraySegment<Int32> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
ArraySegment<Double> |
MemoryView |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Task |
Promise |
Не поддерживаются | Не поддерживаются | Поддерживается | Не поддерживаются |
Action |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Action<T1> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Action<T1, T2> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Action<T1, T2, T3> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Func<TResult> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Func<T1, TResult> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Func<T1, T2, TResult> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Func<T1, T2, T3, TResult> |
Function |
Не поддерживаются | Не поддерживаются | Не поддерживаются | Не поддерживаются |
Следующие условия применяются к сопоставлению типов и маршализированным значениям:
- Столбец
Array of
указывает, можно ли маршалировать тип .NET в виде JSArray
. Пример: C#int[]
(Int32
) сопоставлен с JSArray
Number
s. - При передаче JS значения в C# со значением неправильного типа платформа создает исключение в большинстве случаев. Платформа не выполняет проверку JSтипа во время компиляции.
JSObject
Task
,Exception
и созданиеGCHandle
иArraySegment
прокси-сервер. Вы можете активировать удаление в коде разработчика или разрешить сборку мусора .NET (GC) удалять объекты позже. Эти типы несут значительные затраты на производительность.Array
: маршалинг массива создает копию массива в JS или .NET.MemoryView
MemoryView
JS— это класс среды выполнения .NET WebAssembly для маршалированияSpan
иArraySegment
.- В отличие от маршалинга массива, маршалинг или
Span
ArraySegment
не создает копию базовой памяти. MemoryView
может быть правильно создано средой выполнения .NET WebAssembly. Поэтому невозможно импортировать JS функцию как метод .NET, имеющий параметрSpan
илиArraySegment
.MemoryView
создается только дляSpan
срока вызова взаимодействия. КакSpan
и в стеке вызовов, который не сохраняется после вызова взаимодействия, невозможно экспортировать метод .NET, который возвращаетSpan
.MemoryView
создано дляArraySegment
выживания после вызова взаимодействия и полезно для совместного использования буфера. Вызовdispose()
созданногоMemoryView
ArraySegment
для удаления прокси-сервера и открепляет базовый массив .NET. Рекомендуется вызыватьdispose()
блокtry-finally
дляMemoryView
.
Имя модуля в атрибуте [JSImport]
и вызов загрузки модуля в компоненте JSHost.ImportAsync должен совпадать и быть уникальным в приложении. При создании библиотеки для развертывания в пакете NuGet рекомендуется использовать пространство имен пакета NuGet в качестве префикса в именах модулей. В следующем примере имя модуля отражает Contoso.InteropServices.JavaScript
пакет и папку классов взаимодействия с сообщением пользователя (UserMessages
):
[JSImport("getMessage",
"Contoso.InteropServices.JavaScript.UserMessages.CallJavaScript1")]
Функции, доступные в глобальном пространстве имен, можно импортировать с помощью globalThis
префикса в имени функции и с помощью атрибута [JSImport]
без предоставления имени модуля. В следующем примере console.log
префикс с префиксом globalThis
. Импортированная функция вызывается методом C#Log
, который принимает строковое сообщение C# (message
) и маршалирует строку C# дляString
JSconsole.log
:
[JSImport("globalThis.console.log")]
internal static partial void Log([JSMarshalAs<JSType.String>] string message);
Экспорт скриптов из стандартного модуля JavaScript ES6 с компонентом или размещением с другими статическими ресурсами JavaScript в JS файле (например, wwwroot/js/{FILE NAME}.js
если JS статические ресурсы хранятся в папке js
приложенияwwwroot
, а {FILE NAME}
заполнитель — это имя файла).
В следующем примере JS функция с именем getMessage
экспортируется из коллакуированного JS файла, возвращающего приветственное сообщение "Hello from Blazor!" на португальском языке:
CallJavaScript1.razor.js
:
export function getMessage() {
return 'Olá do Blazor!';
}
Вызов .NET из JavaScript
В этом разделе объясняется, как вызывать методы .NET из JS.
CallDotNet1
Следующий компонент вызываетJS, который напрямую взаимодействует с DOM для отрисовки строки приветственного сообщения:
- Модуль
CallDotNet
JS импортируется асинхронно из файла с сортировкой JS для этого компонента. - Импортированная
setMessage
JS функция вызываетсяSetWelcomeMessage
. - Возвращенное приветственное сообщение отображается
setMessage
в пользовательском интерфейсе черезmessage
поле.
Внимание
В этом примере JS взаимодействие используется для мутации элемента DOM исключительно для демонстрационных целей после отрисовки OnAfterRender
компонента. Как правило, следует изменять только DOM, JS если объект не взаимодействует Blazor. Подход, показанный в этом разделе, аналогичен случаям JS , когда сторонняя библиотека используется в Razor компоненте, где компонент взаимодействует с JS библиотекой через JS взаимодействие, сторонняя JS библиотека взаимодействует с частью DOM и Blazor не участвует непосредственно с обновлениями DOM для этой части DOM. Дополнительные сведения см. в разделе Взаимодействие JavaScript приложения Blazor ASP.NET Core (взаимодействие JS).
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();
}
}
}
Чтобы экспортировать метод .NET, чтобы его можно было вызвать, JSиспользуйте [JSExport]
атрибут.
В следующем примере :
SetWelcomeMessage
вызывает функцию JS с именемsetMessage
. Функция JS вызывается в .NET для получения приветственного сообщения иGetMessageFromDotnet
отображает сообщение в пользовательском интерфейсе.GetMessageFromDotnet
— это метод .NET с[JSExport]
атрибутом, который возвращает приветственное сообщение " Hello from Blazor!" в португальском языке.
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!";
}
}
Пространство имен приложения для предыдущего CallDotNet1
частичного класса BlazorSample
. Пространство имен компонента .BlazorSample.Components.Pages
При использовании предыдущего компонента в локальном тестовом приложении обновите пространство имен приложения, чтобы оно соответствовало приложению. Например, пространство имен компонента — это ContosoApp.Components.Pages
пространство ContosoApp
имен приложения. Дополнительные сведения см. в статье Компоненты Razor ASP.NET Core.
В следующем примере JS функция с именем setMessage
импортируется из файлов с сортировкой JS .
Метод setMessage
:
- Вызовы
globalThis.getDotnetRuntime(0)
для предоставления экземпляра среды выполнения .NET WebAssembly для вызова экспортированных методов .NET. - Получает экспорт сборки JS приложения. Имя сборки приложения в следующем примере
BlazorSample
. BlazorSample.Components.Pages.CallDotNet1.GetMessageFromDotnet
Вызывает метод из экспорта (exports
). Возвращаемое значение, которое является приветственным сообщением, назначаетсяCallDotNet1
тексту компонента<span>
. Пространство имен приложения — этоBlazorSample
пространство имен, аCallDotNet1
пространство имен компонента —BlazorSample.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!";
}
}
Пространство имен приложения для предыдущего CallDotNet1
частичного класса BlazorSample
. Пространство имен компонента .BlazorSample.Pages
При использовании предыдущего компонента в локальном тестовом приложении обновите пространство имен приложения, чтобы оно соответствовало приложению. Например, пространство имен компонента — это ContosoApp.Pages
пространство ContosoApp
имен приложения. Дополнительные сведения см. в статье Компоненты Razor ASP.NET Core.
В следующем примере JS функция с именем setMessage
импортируется из файлов с сортировкой JS .
Метод setMessage
:
- Вызовы
globalThis.getDotnetRuntime(0)
для предоставления экземпляра среды выполнения .NET WebAssembly для вызова экспортированных методов .NET. - Получает экспорт сборки JS приложения. Имя сборки приложения в следующем примере
BlazorSample
. BlazorSample.Pages.CallDotNet1.GetMessageFromDotnet
Вызывает метод из экспорта (exports
). Возвращаемое значение, которое является приветственным сообщением, назначаетсяCallDotNet1
тексту компонента<span>
. Пространство имен приложения — этоBlazorSample
пространство имен, аCallDotNet1
пространство имен компонента —BlazorSample.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();
}
Примечание.
Вызов getAssemblyExports
для получения экспортов может выполняться в инициализаторе JavaScript для доступности в приложении.
Несколько вызовов импорта модуля
JS После загрузки модуля функции модуля JS доступны для компонентов и классов приложения, пока приложение выполняется в окне браузера или на вкладке без перезагрузки приложения вручную. JSHost.ImportAsync можно вызывать несколько раз в одном модуле без значительного штрафа производительности, если:
- Пользователь посещает компонент, вызывающий JSHost.ImportAsync импорт модуля, перемещается от компонента, а затем возвращается к компоненту, где JSHost.ImportAsync вызывается снова для импорта одного модуля.
- Один и тот же модуль используется разными компонентами и загружается JSHost.ImportAsync в каждом из компонентов.
Использование одного модуля JavaScript для компонентов
Прежде чем следовать инструкциям в этом разделе, ознакомьтесь с разделами JavaScript для вызова JavaScript из .NET и вызова .NET из разделов этой статьи, которые предоставляют общие рекомендации по [JSImport]
/[JSExport]
взаимодействиям.
В этом разделе показано, как использовать JS взаимодействие из общего JS модуля в клиентском приложении. Руководство в этом разделе не применимо к Razor библиотекам классов (RCLs).
Используются следующие компоненты, классы, методы C# и JS функции:
Interop
класс (Interop.cs
): настройка взаимодействия импорта и экспорта JS с[JSImport]
[JSExport]
атрибутами для модуля с именемInterop
.GetWelcomeMessage
: метод .NET, вызывающий импортированнуюgetMessage
JS функцию.SetWelcomeMessage
: метод .NET, вызывающий импортированнуюsetMessage
JS функцию.GetMessageFromDotnet
: экспортируемый метод C#, который возвращает строку приветственного сообщения при вызове из JS.
wwwroot/js/interop.js
файл: содержит JS функции.getMessage
: возвращает приветственное сообщение при вызове кода C# в компоненте.setMessage
: вызываетGetMessageFromDotnet
метод C# и назначает возвращенное приветственное сообщение элементу DOM<span>
.
Program.cs
вызовы JSHost.ImportAsync для загрузки модуля изwwwroot/js/interop.js
.CallJavaScript2
компонент (CallJavaScript2.razor
): вызовыGetWelcomeMessage
и отображение возвращаемого приветственного сообщения в пользовательском интерфейсе компонента.CallDotNet2
компонент (CallDotNet2.razor
): вызовы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!";
}
}
В предыдущем примере пространство имен приложения — BlazorSample
это пространство имен и полное пространство имен для классов BlazorSample.JavaScriptInterop
взаимодействия C#.
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 пространство имен доступным в верхней части Program.cs
файла:
using System.Runtime.InteropServices.JavaScript;
Загрузите модуль Program.cs
перед WebAssemblyHost.RunAsync вызовом:
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();
}
}
}
Внимание
В этом примере JS взаимодействие используется для мутации элемента DOM исключительно для демонстрационных целей после отрисовки OnAfterRender
компонента. Как правило, следует изменять только DOM, JS если объект не взаимодействует Blazor. Подход, показанный в этом разделе, аналогичен случаям JS , когда сторонняя библиотека используется в Razor компоненте, где компонент взаимодействует с JS библиотекой через JS взаимодействие, сторонняя JS библиотека взаимодействует с частью DOM и Blazor не участвует непосредственно с обновлениями DOM для этой части DOM. Дополнительные сведения см. в разделе Взаимодействие JavaScript приложения Blazor ASP.NET Core (взаимодействие JS).
Дополнительные ресурсы
- Документация по API
- Запуск .NET из JavaScript
- В репозитории
dotnet/runtime
GitHub:
ASP.NET Core
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по