Spolupráce JavaScriptu [JSImport]
/[JSExport]
s projektem aplikace webAssembly Browser
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Tento článek vysvětluje, jak nastavit projekt aplikace WebAssembly Browser tak, aby spouštět .NET z JavaScriptu (JS) pomocí/JS[JSImport]
[JSExport]
zprostředkovatele komunikace. Další informace a příklady najdete v interoperability JavaScriptu [JSImport]/[JSExport] v .NET WebAssembly.
Další pokyny najdete v pokynech ke konfiguraci a hostování aplikací .NET WebAssembly v úložišti .NET Runtime (dotnet/runtime
) Na GitHubu.
Stávající JS aplikace můžou používat rozšířenou podporu webAssembly na straně klienta k opětovnému použití knihoven .NET z JS nebo k sestavení nového . Aplikace a architektury založené na platformě NET
Poznámka:
Tento článek se zaměřuje na spouštění .NET z JS aplikací bez jakékoli závislosti na Blazor. Pokyny k používání [JSImport]
/[JSExport]
spolupráce v aplikacích najdete v Blazor WebAssembly tématu JavaScript JSImport/JSExport interop s ASP.NET Core .Blazor
Tyto přístupy jsou vhodné, pokud očekáváte Blazor , že se aplikace bude spouštět jenom na WebAssembly (WASM). Knihovny můžou provést kontrolu za běhu a určit, jestli je aplikace spuštěná WASM voláním OperatingSystem.IsBrowser.
Požadavky
wasm-tools
Nainstalujte úlohu do příkazového prostředí pro správu, které přináší související cíle NÁSTROJE MSBuild:
dotnet workload install wasm-tools
Nástroje je možné nainstalovat také prostřednictvím instalačního programu sady Visual Studio v rámci úlohy vývoje pro ASP.NET a web v instalačním programu sady Visual Studio. V seznamu volitelných komponent vyberte možnost nástrojů sestavení .NET WebAssembly.
Volitelně můžete nainstalovat wasm-experimental
úlohu, která přidá následující experimentální šablony projektů:
- Aplikace prohlížeče WebAssembly pro zahájení práce s .NET na WebAssembly v aplikaci prohlížeče
- Konzolová aplikace WebAssembly pro zahájení práce v uzlujskonzolová aplikace založená na
Po instalaci úlohy je možné tyto nové šablony vybrat při vytváření nového projektu. Tato úloha není nutná, pokud plánujete integrovat JS[JSExport]
[JSImport]
/interoperabilitu do existující JS aplikace.
dotnet workload install wasm-experimental
Šablony lze také nainstalovat z Microsoft.NET.Runtime.WebAssembly.Templates
balíčku NuGet pomocí následujícího příkazu:
dotnet new install Microsoft.NET.Runtime.WebAssembly.Templates
Další informace najdete v části Experimentální úlohy a šablony projektů.
Obor názvů
Rozhraní API pro interoperabilitu JS popsané v tomto článku je řízeno atributy v System.Runtime.InteropServices.JavaScript oboru názvů.
Konfigurace projektu
Konfigurace projektu (.csproj
) pro povolení JS spolupráce:
Nastavte moniker cílové architektury (
{TARGET FRAMEWORK}
zástupný symbol):<TargetFramework>{TARGET FRAMEWORK}</TargetFramework>
Podporuje se .NET 7 (
net7.0
) nebo novější.AllowUnsafeBlocks Povolte vlastnost, která umožňuje generátoru kódu v kompilátoru Roslyn používat ukazatele pro JS interoperabilitu:
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Upozorňující
Rozhraní API pro interoperabilitu JS vyžaduje povolení AllowUnsafeBlocks. Při implementaci vlastního nebezpečného kódu v aplikacích .NET buďte opatrní, což může představovat rizika zabezpečení a stability. Další informace naleznete v tématu Nebezpečný kód, typy ukazatelů a ukazatele funkce.
Následuje příklad souboru projektu (.csproj
) po konfiguraci. Zástupný {TARGET FRAMEWORK}
symbol je cílová architektura:
<Project Sdk="Microsoft.NET.Sdk.WebAssembly">
<PropertyGroup>
<TargetFramework>{TARGET FRAMEWORK}</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>
Nastavte moniker cílové architektury:
<TargetFramework>net7.0</TargetFramework>
Podporuje se .NET 7 (
net7.0
) nebo novější.Zadejte
browser-wasm
identifikátor modulu runtime:<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
Zadejte typ výstupu spustitelného souboru:
<OutputType>Exe</OutputType>
AllowUnsafeBlocks Povolte vlastnost, která umožňuje generátoru kódu v kompilátoru Roslyn používat ukazatele pro JS interoperabilitu:
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Upozorňující
Rozhraní API pro interoperabilitu JS vyžaduje povolení AllowUnsafeBlocks. Při implementaci vlastního nebezpečného kódu v aplikacích .NET buďte opatrní, což může představovat rizika zabezpečení a stability. Další informace naleznete v tématu Nebezpečný kód, typy ukazatelů a ukazatele funkce.
Zadejte
WasmMainJSPath
odkaz na soubor na disku. Tento soubor se publikuje v aplikaci, ale pokud integrujete .NET do existující JS aplikace, použití souboru se nevyžaduje.V následujícím příkladu JS je
main.js
soubor na disku , ale jakýkoli název JS souboru je možné použít:<WasmMainJSPath>main.js</WasmMainJSPath>
Ukázkový soubor projektu (.csproj
) po konfiguraci:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
<OutputType>Exe</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<WasmMainJSPath>main.js</WasmMainJSPath>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
Spolupráce JavaScriptu zapnutá WASM
Rozhraní API v následujícím příkladu se naimportují z dotnet.js
. Tato rozhraní API umožňují nastavit pojmenované moduly, které se dají importovat do kódu jazyka C# a volat metody vystavené kódem .NET, včetně Program.Main
.
Důležité
Import a export v tomto článku jsou definovány z pohledu .NET:
- Aplikace importuje JS metody, aby je bylo možné volat z .NET.
- Aplikace exportuje metody .NET, aby je bylo možné volat z JS.
V následujícím příkladu:
Tento
dotnet.js
soubor slouží k vytvoření a spuštění modulu runtime .NET WebAssembly.dotnet.js
se generuje jako součást výstupu sestavení aplikace.Důležité
Pokud se chcete integrovat s existující aplikací, zkopírujte obsah výstupní složky publikování† do prostředků nasazení stávající aplikace, aby bylo možné ho obsluhovat společně s rest aplikací. V případě produkčních nasazení publikujte aplikaci příkazem
dotnet publish -c Release
v příkazovém prostředí a nasaďte obsah výstupní složky s aplikací.†Výsložka výstupu je cílové umístění profilu publikování. Výchozí hodnota pro Release profil v .NET 8 nebo novější je
bin/Release/{TARGET FRAMEWORK}/publish
, kde{TARGET FRAMEWORK}
zástupný symbol je cílová architektura (napříkladnet8.0
).dotnet.create()
nastaví modul runtime .NET WebAssembly.
setModuleImports
přidruží název k modulu JS funkcí pro import do .NET. Modul JS obsahujedom.setInnerText
funkci, která přijímá a selektor prvků a čas k zobrazení aktuálního času stopek v uživatelském rozhraní. Název modulu může být libovolný řetězec (nemusí to být název souboru), ale musí odpovídat názvu použitému vJSImportAttribute
tomto článku (vysvětleno dále v tomto článku). Funkcedom.setInnerText
je importována do jazyka C# a volána metodouSetInnerText
jazyka C#. MetodaSetInnerText
se zobrazí dále v této části.exports.StopwatchSample.Reset()
volání do .NET (StopwatchSample.Reset
) z JS. MetodaReset
C# restartuje stopky, pokud je spuštěná nebo resetuje, pokud není spuštěná. MetodaReset
se zobrazí dále v této části.exports.StopwatchSample.Toggle()
volání do .NET (StopwatchSample.Toggle
) z JS. MetodaToggle
C# spustí nebo zastaví stopky v závislosti na tom, jestli je aktuálně spuštěná nebo ne. MetodaToggle
se zobrazí dále v této části.runMain()
spouštíProgram.Main
.
setModuleImports
přidruží název k modulu JS funkcí pro import do .NET. Modul JS obsahujewindow.location.href
funkci, která vrací adresu aktuální stránky (URL). Název modulu může být libovolný řetězec (nemusí to být název souboru), ale musí odpovídat názvu použitému vJSImportAttribute
tomto článku (vysvětleno dále v tomto článku). Funkcewindow.location.href
je importována do jazyka C# a volána metodouGetHRef
jazyka C#. MetodaGetHRef
se zobrazí dále v této části.exports.MyClass.Greeting()
volání do .NET (MyClass.Greeting
) z JS. MetodaGreeting
C# vrátí řetězec, který obsahuje výsledek voláníwindow.location.href
funkce. MetodaGreeting
se zobrazí dále v této části.dotnet.run()
spouštíProgram.Main
.
JS modul:
import { dotnet } from './_framework/dotnet.js'
const { setModuleImports, getAssemblyExports, getConfig, runMain } = await dotnet
.withApplicationArguments("start")
.create();
setModuleImports('main.js', {
dom: {
setInnerText: (selector, time) =>
document.querySelector(selector).innerText = time
}
});
const config = getConfig();
const exports = await getAssemblyExports(config.mainAssemblyName);
document.getElementById('reset').addEventListener('click', e => {
exports.StopwatchSample.Reset();
e.preventDefault();
});
const pauseButton = document.getElementById('pause');
pauseButton.addEventListener('click', e => {
const isRunning = exports.StopwatchSample.Toggle();
pauseButton.innerText = isRunning ? 'Pause' : 'Start';
e.preventDefault();
});
await runMain();
import { dotnet } from './_framework/dotnet.js'
const { setModuleImports, getAssemblyExports, getConfig } = await dotnet
.withDiagnosticTracing(false)
.withApplicationArgumentsFromQuery()
.create();
setModuleImports('main.js', {
window: {
location: {
href: () => globalThis.window.location.href
}
}
});
const config = getConfig();
const exports = await getAssemblyExports(config.mainAssemblyName);
const text = exports.MyClass.Greeting();
console.log(text);
document.getElementById('out').innerHTML = text;
await dotnet.run();
import { dotnet } from './dotnet.js'
const is_browser = typeof window != "undefined";
if (!is_browser) throw new Error(`Expected to be running in a browser`);
const { setModuleImports, getAssemblyExports, getConfig } =
await dotnet.create();
setModuleImports("main.js", {
window: {
location: {
href: () => globalThis.window.location.href
}
}
});
const config = getConfig();
const exports = await getAssemblyExports(config.mainAssemblyName);
const text = exports.MyClass.Greeting();
console.log(text);
document.getElementById("out").innerHTML = text;
await dotnet.run();
Pokud chcete naimportovat JS funkci, aby ji bylo možné volat z jazyka C#, použijte novou JSImportAttribute funkci u odpovídajícího podpisu metody. Prvním parametrem funkce JSImportAttribute , která JS se má importovat, a druhým parametrem je název modulu.
V následujícím příkladu dom.setInnerText
se funkce volá z main.js
modulu, když SetInnerText
se volá metoda:
[JSImport("dom.setInnerText", "main.js")]
internal static partial void SetInnerText(string selector, string content);
V následujícím příkladu window.location.href
se funkce volá z main.js
modulu, když GetHRef
se volá metoda:
[JSImport("window.location.href", "main.js")]
internal static partial string GetHRef();
V podpisu importované metody můžete použít typy .NET pro parametry a návratové hodnoty, které jsou automaticky zařazovány modulem runtime. Slouží JSMarshalAsAttribute<T> k řízení způsobu, jakým jsou importované parametry metody zařazovány. Můžete se například rozhodnout, že zařadíte jako long
System.Runtime.InteropServices.JavaScript.JSType.Number nebo System.Runtime.InteropServices.JavaScript.JSType.BigInt. Zpětná volání můžete předat Action/Func<TResult> jako parametry, které jsou zařazovány jako volatelné JS funkce. Můžete předat odkazy na objekty i JS spravované objekty a jsou zařazovány jako proxy objekty, přičemž objekt je aktivní v rámci hranice, dokud se proxy neshromáždí. Můžete také importovat a exportovat asynchronní metody s Task výsledkem, které jsou zařazovány jako JS přísliby. Většina zařazovaných typů funguje v obou směrech jako parametry a jako návratové hodnoty u importovaných i exportovaných metod.
Další informace o mapování typů a příklady najdete v interoperability JavaScriptu [JSImport]/[JSExport] v .NET WebAssembly.
Funkce přístupné pro globální obor názvů je možné importovat pomocí globalThis
předpony v názvu funkce a pomocí atributu [JSImport]
bez zadání názvu modulu. V následujícím příkladu console.log
je předpona globalThis
. Importovaná funkce je volána metodou jazyka C# Log
, která přijímá řetězcovou zprávu jazyka C# (message
) a zařadí řetězec jazyka JSString
console.log
C# na :
[JSImport("globalThis.console.log")]
internal static partial void Log([JSMarshalAs<JSType.String>] string message);
Chcete-li exportovat metodu .NET, aby ji bylo možné volat z JS, použijte JSExportAttribute.
V následujícím příkladu je každá metoda exportována do JS funkcí a lze ji volat z JS funkcí:
- Metoda
Toggle
spustí nebo zastaví stopky v závislosti na jeho spuštěném stavu. - Metoda
Reset
restartuje stopky, pokud je spuštěná nebo resetuje, pokud není spuštěná. - Metoda
IsRunning
označuje, jestli je stopky spuštěné.
[JSExport]
internal static bool Toggle()
{
if (stopwatch.IsRunning)
{
stopwatch.Stop();
return false;
}
else
{
stopwatch.Start();
return true;
}
}
[JSExport]
internal static void Reset()
{
if (stopwatch.IsRunning)
stopwatch.Restart();
else
stopwatch.Reset();
Render();
}
[JSExport]
internal static bool IsRunning() => stopwatch.IsRunning;
V následujícím příkladu Greeting
vrátí metoda řetězec, který obsahuje výsledek volání GetHRef
metody. Jak je znázorněno výše, metoda jazyka GetHref
C# volá JS funkci window.location.href
z main.js
modulu. window.location.href
vrátí adresu aktuální stránky (URL):
[JSExport]
internal static string Greeting()
{
var text = $"Hello, World! Greetings from {GetHRef()}";
Console.WriteLine(text);
return text;
}
Experimentální úlohy a šablony projektů
Pokud chcete předvést JS funkce vzájemné spolupráce a získat JS šablony projektů spolupráce, nainstalujte wasm-experimental
úlohu:
dotnet workload install wasm-experimental
Úloha wasm-experimental
obsahuje dvě šablony projektu: wasmbrowser
a wasmconsole
. Tyto šablony jsou v tuto chvíli experimentální, což znamená, že se vyvíjí pracovní postup vývojáře pro šablony. Rozhraní .NET a JS rozhraní API použitá v šablonách jsou však podporována v .NET 8 a poskytují základ pro použití rozhraní .NET WASM z JS.
Šablony lze také nainstalovat z Microsoft.NET.Runtime.WebAssembly.Templates
balíčku NuGet pomocí následujícího příkazu:
dotnet new install Microsoft.NET.Runtime.WebAssembly.Templates
Aplikace prohlížeče
Aplikaci prohlížeče můžete vytvořit pomocí wasmbrowser
šablony z příkazového řádku, která vytvoří webovou aplikaci, která demonstruje použití .NET a JS společně v prohlížeči:
dotnet new wasmbrowser
Alternativně v sadě Visual Studio můžete aplikaci vytvořit pomocí WebAssembly Browser App šablony projektu.
Sestavte aplikaci ze sady Visual Studio nebo pomocí rozhraní příkazového řádku .NET:
dotnet build
Sestavte a spusťte aplikaci ze sady Visual Studio nebo pomocí rozhraní příkazového řádku .NET:
dotnet run
Případně nainstalujte a použijte dotnet serve
příkaz:
dotnet serve -d:bin/$(Configuration)/{TARGET FRAMEWORK}/publish
V předchozím příkladu {TARGET FRAMEWORK}
je zástupný symbol moniker cílové architektury.
Uzel.js konzolová aplikace
Pomocí šablony můžete vytvořit konzolovou aplikaciwasmconsole
, která vytvoří aplikaci, která běží pod WASM uzlem nebo js konzolovou aplikací V8:
dotnet new wasmconsole
Alternativně v sadě Visual Studio můžete aplikaci vytvořit pomocí WebAssembly Console App šablony projektu.
Sestavte aplikaci ze sady Visual Studio nebo pomocí rozhraní příkazového řádku .NET:
dotnet build
Sestavte a spusťte aplikaci ze sady Visual Studio nebo pomocí rozhraní příkazového řádku .NET:
dotnet run
Případně spusťte libovolný statický souborový server z výstupního adresáře publikování, který soubor obsahuje main.mjs
:
node bin/$(Configuration)/{TARGET FRAMEWORK}/{PATH}/main.mjs
V předchozím příkladu {TARGET FRAMEWORK}
je zástupný symbol moniker cílové architektury a {PATH}
zástupný symbol je cesta k main.mjs
souboru.
Další materiály
- Interoperabilita JavaScriptu [JSImport]/[JSExport] v .NET WebAssembly
- JavaScript JSImport/JSExport interop s ASP.NET Core Blazor
- Dokumentace k rozhraní API
- V úložišti
dotnet/runtime
GitHub: - Použití .NET z libovolné javascriptové aplikace v .NET 7