Megosztás a következőn keresztül:


.NET-metódusok meghívása JavaScript-függvényekből a ASP.NET Core-ban Blazor

Note

Ez nem a cikk legújabb verziója. Az aktuális kiadásról a cikk .NET 10-es verziójában olvashat.

Warning

A ASP.NET Core ezen verziója már nem támogatott. További információt a .NET és a .NET Core támogatási szabályzatában talál. A jelen cikk .NET 9-es verzióját lásd az aktuális kiadásért .

Ez a cikk bemutatja, hogyan hívhat meg .NET-metódusokat a JavaScriptből (JS).

A függvények .NET-ből való meghívásáról JS további információt a .NET-metódusok JavaScript-függvényeinek meghívása a ASP.NET Core-ban Blazorcímű témakörben talál.

Statikus .NET-metódus meghívása

Ha statikus .NET-metódust szeretne meghívni a JavaScriptből (JS), használja a JS függvényeket:

  • DotNet.invokeMethodAsync (ajánlott): Aszinkron mind a kiszolgálóoldali, mind az ügyféloldali összetevők esetében.
  • DotNet.invokeMethod: Csak ügyféloldali összetevők esetén szinkron.

Adja meg a metódust tartalmazó szerelvény nevét, a statikus .NET metódus azonosítóját és az argumentumokat.

Az alábbi példában:

  • A {PACKAGE ID/ASSEMBLY NAME} helyőrző a projekt csomagazonosítója (<PackageId> a projektfájlban) egy alkalmazás kódtárának vagy szerelvénynevének.
  • A {.NET METHOD ID} helyőrző a .NET metódusazonosító.
  • A {ARGUMENTS} helyőrző nem kötelező, vesszővel tagolt argumentumokat ad át a metódusnak, amelyek mindegyikének JSON-szerializálhatónak kell lennie.
DotNet.invokeMethodAsync('{PACKAGE ID/ASSEMBLY NAME}', '{.NET METHOD ID}', {ARGUMENTS});

DotNet.invokeMethodAsync A művelet eredményét képviselő értéket ad JS Promise vissza. DotNet.invokeMethod (ügyféloldali összetevők) a művelet eredményét adja vissza.

Important

Kiszolgálóoldali összetevők esetén az aszinkron függvényt (invokeMethodAsync) javasoljuk a szinkron verzió (invokeMethod) felett.

A .NET metódusnak nyilvánosnak, statikusnak és attribútummal kell rendelkeznie[JSInvokable].

Az alábbi példában:

  • A {<T>} helyőrző a visszatérési típust jelzi, amely csak az értékeket visszaadó metódusokhoz szükséges.
  • A {.NET METHOD ID} helyőrző a metódus azonosítója.
@code {
    [JSInvokable]
    public static Task{<T>} {.NET METHOD ID}()
    {
        ...
    }
}

Note

A nyitott általános metódusok meghívása statikus .NET-metódusokkal nem támogatott, de a példánymetelyekkel támogatott. További információt a .NET általános osztály metódusainak hívása című szakaszban talál.

A következő összetevőben a ReturnArrayAsync C# metódus egy tömböt int ad vissza. Az [JSInvokable] attribútum a metódusra lesz alkalmazva, így a metódus invokábilissá JSválik.

CallDotnet1.razor:

@page "/call-dotnet-1"
@implements IAsyncDisposable
@inject IJSRuntime JS

<PageTitle>Call .NET 1</PageTitle>

<h1>Call .NET Example 1</h1>

<p>
    <button id="btn">Trigger .NET static method</button>
</p>

<p>
    See the result in the developer tools console.
</p>

@code {
    private IJSObjectReference? module;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            module = await JS.InvokeAsync<IJSObjectReference>("import",
                "./Components/Pages/CallDotnet1.razor.js");

            await module.InvokeVoidAsync("addHandlers");
        }
    }

    [JSInvokable]
    public static Task<int[]> ReturnArrayAsync() =>
        Task.FromResult(new int[] { 11, 12, 13 });

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
        {
            try
            {
                await module.DisposeAsync();
            }
            catch (JSDisconnectedException)
            {
            }
        }
    }
}

CallDotnet1.razor.js:

export function returnArrayAsync() {
  DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync')
    .then(data => {
      console.log(data);
    });
}

export function addHandlers() {
  const btn = document.getElementById("btn");
  btn.addEventListener("click", returnArrayAsync);
}

A addHandlersJS függvény egy eseményt click ad hozzá a gombhoz. A returnArrayAsyncJS függvény kezelőként van hozzárendelve.

A returnArrayAsyncJS függvény meghívja az ReturnArrayAsync összetevő .NET metódusát, amely naplózza az eredményt a böngésző webfejlesztői eszközeinek konzolján. BlazorSample az alkalmazás szerelvényének neve.

CallDotnet1.razor:

@page "/call-dotnet-1"
@implements IAsyncDisposable
@inject IJSRuntime JS

<PageTitle>Call .NET 1</PageTitle>

<h1>Call .NET Example 1</h1>

<p>
    <button id="btn">Trigger .NET static method</button>
</p>

<p>
    See the result in the developer tools console.
</p>

@code {
    private IJSObjectReference? module;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            module = await JS.InvokeAsync<IJSObjectReference>("import",
                "./Components/Pages/CallDotnet1.razor.js");

            await module.InvokeVoidAsync("addHandlers");
        }
    }

    [JSInvokable]
    public static Task<int[]> ReturnArrayAsync() =>
        Task.FromResult(new int[] { 11, 12, 13 });

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
        {
            try
            {
                await module.DisposeAsync();
            }
            catch (JSDisconnectedException)
            {
            }
        }
    }
}

CallDotnet1.razor.js:

export function returnArrayAsync() {
  DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync')
    .then(data => {
      console.log(data);
    });
}

export function addHandlers() {
  const btn = document.getElementById("btn");
  btn.addEventListener("click", returnArrayAsync);
}

A addHandlersJS függvény egy eseményt click ad hozzá a gombhoz. A returnArrayAsyncJS függvény kezelőként van hozzárendelve.

A returnArrayAsyncJS függvény meghívja az ReturnArrayAsync összetevő .NET metódusát, amely naplózza az eredményt a böngésző webfejlesztői eszközeinek konzolján. BlazorSample az alkalmazás szerelvényének neve.

CallDotNetExample1.razor:

@page "/call-dotnet-example-1"

<h1>Call .NET Example 1</h1>

<p>
    <button onclick="returnArrayAsync()">
        Trigger .NET static method
    </button>
</p>

@code {
    [JSInvokable]
    public static Task<int[]> ReturnArrayAsync()
    {
        return Task.FromResult(new int[] { 1, 2, 3 });
    }
}

CallDotNetExample1.razor:

@page "/call-dotnet-example-1"

<h1>Call .NET Example 1</h1>

<p>
    <button onclick="returnArrayAsync()">
        Trigger .NET static method
    </button>
</p>

@code {
    [JSInvokable]
    public static Task<int[]> ReturnArrayAsync()
    {
        return Task.FromResult(new int[] { 1, 2, 3 });
    }
}

CallDotNetExample1.razor:

@page "/call-dotnet-example-1"

<h1>Call .NET Example 1</h1>

<p>
    <button onclick="returnArrayAsync()">
        Trigger .NET static method
    </button>
</p>

@code {
    [JSInvokable]
    public static Task<int[]> ReturnArrayAsync()
    {
        return Task.FromResult(new int[] { 1, 2, 3 });
    }
}

CallDotNetExample1.razor:

@page "/call-dotnet-example-1"

<h1>Call .NET Example 1</h1>

<p>
    <button onclick="returnArrayAsync()">
        Trigger .NET static method
    </button>
</p>

@code {
    [JSInvokable]
    public static Task<int[]> ReturnArrayAsync()
    {
        return Task.FromResult(new int[] { 1, 2, 3 });
    }
}

Az <button> elem onclick HTML-attribútuma a JavaScript onclick eseménykezelőjének hozzárendelése az click események feldolgozására, és nem a(z) Blazor@onclick direktíva attribútuma. A returnArrayAsyncJS függvény kezelőként van hozzárendelve.

Az alábbi returnArrayAsyncJS függvény meghívja az ReturnArrayAsync összetevő .NET metódusát, amely naplózza az eredményt a böngésző webfejlesztői eszközeinek konzolján. BlazorSample az alkalmazás szerelvényének neve.

<script>
  window.returnArrayAsync = () => {
    DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync')
      .then(data => {
        console.log(data);
      });
    };
</script>

Note

A JS helyére és az éles alkalmazásokkal kapcsolatos ajánlásainkra vonatkozó általános útmutatásért nézze meg a JavaScript-helyet az ASP.NET Core Blazor alkalmazásokban.

Ha a Trigger .NET static method gomb ki van jelölve, a böngésző fejlesztői eszközeinek konzoljának kimenete megjeleníti a tömbadatokat. A kimenet formátuma némileg eltér a böngészőktől. Az alábbi kimenet a Microsoft Edge által használt formátumot mutatja be:

Array(3) [ 11, 12, 13 ]

Adatok átadása .NET-metódusnak a invokeMethodAsync függvény meghívásakor az adatok argumentumként való átadásával.

Az adatok .NET-nek való átadásának bemutatásához adja át a kiindulási pozíciót annak a ReturnArrayAsync metódusnak, amelyben a metódus meghívása JStörténik:

export function returnArrayAsync() {
  DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync', 14)
    .then(data => {
      console.log(data);
    });
}
<script>
  window.returnArrayAsync = () => {
    DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync', 14)
      .then(data => {
        console.log(data);
      });
    };
</script>

Az összetevő invokable ReturnArrayAsync metódusa megkapja a kiindulási pozíciót, és abból építi ki a tömböt. A rendszer a következő tömböt adja vissza a konzolra való naplózáshoz:

[JSInvokable]
public static Task<int[]> ReturnArrayAsync(int startPosition) => 
    Task.FromResult(Enumerable.Range(startPosition, 3).ToArray());

Az alkalmazás újrafordítása és a böngésző frissítése után a következő kimenet jelenik meg a böngésző konzolján a gomb kiválasztásakor:

Array(3) [ 14, 15, 16 ]

A hívás .NET metódusazonosítója a JS .NET metódus neve, de az attribútumkonstruktor használatával [JSInvokable] megadhat egy másik azonosítót. Az alábbi példában a DifferentMethodName metódust a ReturnArrayAsync metódusazonosítóval jelölték:

[JSInvokable("DifferentMethodName")]

A DotNet.invokeMethodAsync (kiszolgálóoldali vagy ügyféloldali összetevők) vagy DotNet.invokeMethod (csak ügyféloldali összetevők esetén) hívásban hívja meg a DifferentMethodName a ReturnArrayAsync .NET metódus végrehajtására.

  • DotNet.invokeMethodAsync('BlazorSample', 'DifferentMethodName');
  • DotNet.invokeMethod('BlazorSample', 'DifferentMethodName'); (csak ügyféloldali összetevők)

Note

A ReturnArrayAsync metódus-példa ebben a szakaszban a Task eredményét adja vissza explicit C# async és await kulcsszavak használata nélkül. Azoknál a metódusoknál, amelyek a async kulcsszót használják az aszinkron műveletek értékének visszaadására, jellemző a await és await használatával történő kódolási módszer.

ReturnArrayAsync módszer, amely async és await kulcsszavakkal van összeállítva:

[JSInvokable]
public static async Task<int[]> ReturnArrayAsync() => 
    await Task.FromResult(new int[] { 11, 12, 13 });

További információért lásd a Aszinkron programozás async és await használatával című részt a C# útmutatóban.

JavaScript-objektum és adathivatkozások létrehozása a .NET-nek való továbbításhoz

A DotNet.createJSObjectReference(jsObject) objektumhivatkozás létrehozása érdekében hívja meg a JS, hogy azt át lehessen adni a .NET-nek, ahol a jsObject az a JS Object, amelyet a JS objektumhivatkozás létrehozásához használnak. Az alábbi példa egy nem szerializálható window objektumra mutató hivatkozást ad át a .NET-nek, amely a ReceiveWindowObject C# metódusban fogadja a következőként IJSObjectReference:

DotNet.invokeMethodAsync('{PACKAGE ID/ASSEMBLY NAME}', 'ReceiveWindowObject', 
  DotNet.createJSObjectReference(window));
[JSInvokable]
public static void ReceiveWindowObject(IJSObjectReference objRef)
{
    ...
}

Az előző példában a {PACKAGE ID/ASSEMBLY NAME} helyőrző a projekt csomagazonosítója (<PackageId> a projektfájlban) egy alkalmazás kódtárának vagy szerelvénynevének.

Note

Az előző példa nem követeli meg az JSObjectReferenceobjektum eltávolítását, mivel az objektumra mutató hivatkozás nem található a window fájlban JS.

Egy JSObjectReference hivatkozás fenntartása megköveteli annak felszabadítását, hogy elkerüljük a JS memória szivárgását a kliensnél. Az alábbi példa újraadja az előző kódot, hogy rögzítse a JSObjectReferencehivatkozásra mutató hivatkozást, majd a hivatkozás megsemmisítésére DotNet.disposeJSObjectReference() irányuló hívást:

var jsObjectReference = DotNet.createJSObjectReference(window);

DotNet.invokeMethodAsync('{PACKAGE ID/ASSEMBLY NAME}', 'ReceiveWindowObject', jsObjectReference);

DotNet.disposeJSObjectReference(jsObjectReference);

Az előző példában a {PACKAGE ID/ASSEMBLY NAME} helyőrző a projekt csomagazonosítója (<PackageId> a projektfájlban) egy alkalmazás kódtárának vagy szerelvénynevének.

DotNet.createJSStreamReference(streamReference) Hívás egy adatfolyam-hivatkozás JS létrehozásához, hogy az átadható legyen a .NET-nek, ahol streamReference egy ArrayBuffer, Blob vagy bármilyen típusú tömb, például Uint8Array vagy Float32Array, amit a JS streamhivatkozás létrehozásához használtak.

Példány .NET-metódus meghívása

Példány .NET-metódusának meghívása JavaScriptből (JS):

  • Adja át a .NET-példányt hivatkozásként JS úgy, hogy csomagolja be a példányt egy DotNetObjectReference objektumba, és hívja meg a Create-t rajta.

  • A .NET példány egy metódusának meghívása az átadott JS-ból történik az invokeMethodAsync (ajánlott) vagy invokeMethod (csak ügyféloldali összetevők) használatával. Adja meg a példány .NET metódusának azonosítóját és az argumentumokat. A .NET-példány argumentumként is átadható más .NET-metódusok JSmeghívásakor.

    Az alábbi példában:

    • dotNetHelper DotNetObjectReference egy.
    • A {.NET METHOD ID} helyőrző a .NET metódusazonosító.
    • A {ARGUMENTS} helyőrző nem kötelező, vesszővel tagolt argumentumokat ad át a metódusnak, amelyek mindegyikének JSON-szerializálhatónak kell lennie.
    dotNetHelper.invokeMethodAsync('{.NET METHOD ID}', {ARGUMENTS});
    

    Note

    invokeMethodAsync és invokeMethod ne fogadj el szerelvénynévparamétert egy példánymetódus meghívásakor.

    invokeMethodAsync A művelet eredményét képviselő értéket ad JS Promise vissza. invokeMethod (csak ügyféloldali összetevők esetén) a művelet eredményét adja vissza.

    Important

    Kiszolgálóoldali összetevők esetén az aszinkron függvényt (invokeMethodAsync) javasoljuk a szinkron verzió (invokeMethod) felett.

  • Dobja el a DotNetObjectReference.

A cikk következő szakaszai a .NET-metódus példányának meghívására szolgáló különböző megközelítéseket mutatják be:

Kerülje a JavaScript által meghívható .NET metódusok eltávolítását.

Ez a szakasz az ügyféloldali alkalmazásokra vonatkozik, amelyeken engedélyezve van az idő előtti fordítás ésa futásidejű újrakapcsolás .

A következő szakaszokban szereplő példák közül több is egy osztálypéldány-megközelítésen alapul, ahol az attribútummal[JSInvokable] megjelölt JavaScript-invokable .NET metódus egy olyan osztály tagja, amely nem Razor összetevő. Ha az ilyen .NET-metódusok egy Razor összetevőben találhatók, akkor védve vannak a futtatókörnyezet újrakapcsolása vagy vágása ellen. Annak érdekében, hogy megvédje a .NET-metódusokat az összetevőkön kívüli Razor vágástól, implementálja a metódusokat az DynamicDependency osztály konstruktorának attribútumával, ahogy az alábbi példa is mutatja:

using System.Diagnostics.CodeAnalysis;
using Microsoft.JSInterop;

public class ExampleClass {

    [DynamicDependency(nameof(ExampleJSInvokableMethod))]
    public ExampleClass()
    {
    }

    [JSInvokable]
    public string ExampleJSInvokableMethod()
    {
        ...
    }
}

További információért lásd: .NET-könyvtárak előkészítése trimmeléshez: DynamicDependency.

Egy DotNetObjectReference átadása egy adott JavaScript-függvénynek

Az ebben a szakaszban szereplő példa bemutatja, hogyan adhat át egy DotNetObjectReference egy adott JavaScript-függvénynek.JS

Az alábbi sayHello1JS függvény DotNetObjectReference fogad, és a invokeMethodAsync segítségével meghívja egy összetevő GetHelloMessage .NET-metódusát.

<script>
  window.sayHello1 = (dotNetHelper) => {
    return dotNetHelper.invokeMethodAsync('GetHelloMessage');
  };
</script>

Note

A JS helyére és az éles alkalmazásokkal kapcsolatos ajánlásainkra vonatkozó általános útmutatásért nézze meg a JavaScript-helyet az ASP.NET Core Blazor alkalmazásokban.

Az előző példában a változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.

A következő összetevőhöz:

  • Az összetevő egy JS-invokable .NET metódust tartalmaz, amelynek neve GetHelloMessage.
  • Ha a Trigger .NET instance method gombot kiválasztják, akkor a JS függvény hívódik meg a sayHello1-dal.
  • sayHello1:
    • Meghívja GetHelloMessage, majd megkapja az üzenet eredményét.
    • Visszaadja az üzenet eredményét a hívási TriggerDotNetInstanceMethod metódusnak.
  • A beküldött sayHello1result üzenet megjelenik a felhasználó számára.
  • A memóriaszivárgás elkerülése és a szemétgyűjtés lehetővé tétele érdekében a DotNetObjectReference által létrehozott .NET objektum hivatkozást a Dispose metódusban szabadítjuk fel.

CallDotnet2.razor:

@page "/call-dotnet-2"
@implements IDisposable
@inject IJSRuntime JS

<PageTitle>Call .NET 2</PageTitle>

<h1>Call .NET Example 2</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private DotNetObjectReference<CallDotnet2>? objRef;

    protected override void OnInitialized() =>
        objRef = DotNetObjectReference.Create(this);

    public async Task TriggerDotNetInstanceMethod() =>
        result = await JS.InvokeAsync<string>("sayHello1", objRef);

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {name}!";

    public void Dispose() => objRef?.Dispose();
}

CallDotnet2.razor:

@page "/call-dotnet-2"
@implements IDisposable
@inject IJSRuntime JS

<PageTitle>Call .NET 2</PageTitle>

<h1>Call .NET Example 2</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private DotNetObjectReference<CallDotnet2>? objRef;

    protected override void OnInitialized() =>
        objRef = DotNetObjectReference.Create(this);

    public async Task TriggerDotNetInstanceMethod() =>
        result = await JS.InvokeAsync<string>("sayHello1", objRef);

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {name}!";

    public void Dispose() => objRef?.Dispose();
}

CallDotNetExample2.razor:

@page "/call-dotnet-example-2"
@implements IDisposable
@inject IJSRuntime JS

<h1>Call .NET Example 2</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private DotNetObjectReference<CallDotNetExample2>? objRef;

    protected override void OnInitialized()
    {
        objRef = DotNetObjectReference.Create(this);
    }

    public async Task TriggerDotNetInstanceMethod()
    {
        result = await JS.InvokeAsync<string>("sayHello1", objRef);
    }

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {name}!";

    public void Dispose()
    {
        objRef?.Dispose();
    }
}

CallDotNetExample2.razor:

@page "/call-dotnet-example-2"
@implements IDisposable
@inject IJSRuntime JS

<h1>Call .NET Example 2</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private DotNetObjectReference<CallDotNetExample2>? objRef;

    protected override void OnInitialized()
    {
        objRef = DotNetObjectReference.Create(this);
    }

    public async Task TriggerDotNetInstanceMethod()
    {
        result = await JS.InvokeAsync<string>("sayHello1", objRef);
    }

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {name}!";

    public void Dispose()
    {
        objRef?.Dispose();
    }
}

CallDotNetExample2.razor:

@page "/call-dotnet-example-2"
@implements IDisposable
@inject IJSRuntime JS

<h1>Call .NET Example 2</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string name;
    private string result;
    private DotNetObjectReference<CallDotNetExample2> objRef;

    protected override void OnInitialized()
    {
        objRef = DotNetObjectReference.Create(this);
    }

    public async Task TriggerDotNetInstanceMethod()
    {
        result = await JS.InvokeAsync<string>("sayHello1", objRef);
    }

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {name}!";

    public void Dispose()
    {
        objRef?.Dispose();
    }
}

CallDotNetExample2.razor:

@page "/call-dotnet-example-2"
@implements IDisposable
@inject IJSRuntime JS

<h1>Call .NET Example 2</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string name;
    private string result;
    private DotNetObjectReference<CallDotNetExample2> objRef;

    protected override void OnInitialized()
    {
        objRef = DotNetObjectReference.Create(this);
    }

    public async Task TriggerDotNetInstanceMethod()
    {
        result = await JS.InvokeAsync<string>("sayHello1", objRef);
    }

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {name}!";

    public void Dispose()
    {
        objRef?.Dispose();
    }
}

Az előző példában a változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.

Az alábbi útmutatással argumentumokat adhat át egy példánymetódusnak:

Adjon hozzá paramétereket a .NET metódus meghívásához. Az alábbi példában egy nevet ad át a metódusnak. Szükség szerint adjon hozzá további paramétereket a listához.

<script>
  window.sayHello2 = (dotNetHelper, name) => {
    return dotNetHelper.invokeMethodAsync('GetHelloMessage', name);
  };
</script>

Az előző példában a változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.

Adja meg a paraméterlistát a .NET metódusnak.

CallDotnet3.razor:

@page "/call-dotnet-3"
@implements IDisposable
@inject IJSRuntime JS

<PageTitle>Call .NET 3</PageTitle>

<h1>Call .NET Example 3</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private DotNetObjectReference<CallDotnet3>? objRef;

    protected override void OnInitialized() => 
        objRef = DotNetObjectReference.Create(this);

    public async Task TriggerDotNetInstanceMethod() =>
        result = await JS.InvokeAsync<string>("sayHello2", objRef, name);

    [JSInvokable]
    public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";

    public void Dispose() => objRef?.Dispose();
}

CallDotnet3.razor:

@page "/call-dotnet-3"
@implements IDisposable
@inject IJSRuntime JS

<PageTitle>Call .NET 3</PageTitle>

<h1>Call .NET Example 3</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private DotNetObjectReference<CallDotnet3>? objRef;

    protected override void OnInitialized() => 
        objRef = DotNetObjectReference.Create(this);

    public async Task TriggerDotNetInstanceMethod() =>
        result = await JS.InvokeAsync<string>("sayHello2", objRef, name);

    [JSInvokable]
    public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";

    public void Dispose() => objRef?.Dispose();
}

CallDotNetExample3.razor:

@page "/call-dotnet-example-3"
@implements IDisposable
@inject IJSRuntime JS

<h1>Call .NET Example 3</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private DotNetObjectReference<CallDotNetExample3>? objRef;

    protected override void OnInitialized()
    {
        objRef = DotNetObjectReference.Create(this);
    }

    public async Task TriggerDotNetInstanceMethod()
    {
        result = await JS.InvokeAsync<string>("sayHello2", objRef, name);
    }

    [JSInvokable]
    public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";

    public void Dispose()
    {
        objRef?.Dispose();
    }
}

CallDotNetExample3.razor:

@page "/call-dotnet-example-3"
@implements IDisposable
@inject IJSRuntime JS

<h1>Call .NET Example 3</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private DotNetObjectReference<CallDotNetExample3>? objRef;

    protected override void OnInitialized()
    {
        objRef = DotNetObjectReference.Create(this);
    }

    public async Task TriggerDotNetInstanceMethod()
    {
        result = await JS.InvokeAsync<string>("sayHello2", objRef, name);
    }

    [JSInvokable]
    public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";

    public void Dispose()
    {
        objRef?.Dispose();
    }
}

CallDotNetExample3.razor:

@page "/call-dotnet-example-3"
@implements IDisposable
@inject IJSRuntime JS

<h1>Call .NET Example 3</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string name;
    private string result;
    private DotNetObjectReference<CallDotNetExample3> objRef;

    protected override void OnInitialized()
    {
        objRef = DotNetObjectReference.Create(this);
    }

    public async Task TriggerDotNetInstanceMethod()
    {
        result = await JS.InvokeAsync<string>("sayHello2", objRef, name);
    }

    [JSInvokable]
    public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";

    public void Dispose()
    {
        objRef?.Dispose();
    }
}

CallDotNetExample3.razor:

@page "/call-dotnet-example-3"
@implements IDisposable
@inject IJSRuntime JS

<h1>Call .NET Example 3</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string name;
    private string result;
    private DotNetObjectReference<CallDotNetExample3> objRef;

    protected override void OnInitialized()
    {
        objRef = DotNetObjectReference.Create(this);
    }

    public async Task TriggerDotNetInstanceMethod()
    {
        result = await JS.InvokeAsync<string>("sayHello2", objRef, name);
    }

    [JSInvokable]
    public string GetHelloMessage(string passedName) => $"Hello, {passedName}!";

    public void Dispose()
    {
        objRef?.Dispose();
    }
}

Az előző példában a változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.

Adjon át egy DotNetObjectReference osztályt, amely több JavaScript-függvényt tartalmaz.

Az ebben a szakaszban található példa bemutatja, hogyan adhat át egy DotNetObjectReference JavaScript-osztályt többJS függvényt tartalmazó osztálynak.

Hozzon létre és adjon át egy DotNetObjectReferenceéletciklus-metódusbólOnAfterRenderAsync egy JS osztályt több függvény számára. Győződjön meg arról, hogy a .NET-kód az alábbi példában látható módon felszabadítja a DotNetObjectReference erőforrást.

A következő összetevőben a Trigger JS function gombok a JS függvényeket a JSonclick tulajdonság beállításával hívják meg, nem pedig a Blazor@onclick direktíva attribútuma által.

CallDotNetExampleOneHelper.razor:

@page "/call-dotnet-example-one-helper"
@implements IAsyncDisposable
@inject IJSRuntime JS

<PageTitle>Call .NET Example</PageTitle>

<h1>Pass <code>DotNetObjectReference</code> to a JavaScript class</h1>

<p>
    <label>
        Message: <input @bind="name" />
    </label>
</p>

<p>
    <button id="sayHelloBtn">
        Trigger JS function <code>sayHello</code>
    </button>
</p>

<p>
    <button id="welcomeVisitorBtn">
        Trigger JS function <code>welcomeVisitor</code>
    </button>
</p>

@code {
    private IJSObjectReference? module;
    private string? name;
    private DotNetObjectReference<CallDotNetExampleOneHelper>? dotNetHelper;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            module = await JS.InvokeAsync<IJSObjectReference>("import",
                "./Components/Pages/CallDotNetExampleOneHelper.razor.js");

            dotNetHelper = DotNetObjectReference.Create(this);
            await module.InvokeVoidAsync("GreetingHelpers.setDotNetHelper", 
                dotNetHelper);

            await module.InvokeVoidAsync("addHandlers");
        }
    }

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {name}!";

    [JSInvokable]
    public string GetWelcomeMessage() => $"Welcome, {name}!";

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
        {
            try
            {
                await module.DisposeAsync();
            }
            catch (JSDisconnectedException)
            {
            }
        }

        dotNetHelper?.Dispose();
    }
}

Az előző példában:

  • JS egy injektált IJSRuntime példány. A IJSRuntime-t a Blazor keretrendszer regisztrálja.
  • A változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.
  • Az összetevőnek explicit módon el kell végeznie a DotNetObjectReference szemétgyűjtést, és meg kell akadályoznia a memóriaszivárgást.
  • JSDisconnectedException a modul ártalmatlanítása során megszorul, ha BlazorSignalR áramköre elvész. Ha az előző kódot egy Blazor WebAssembly alkalmazásban használják, nincs SignalR kapcsolat, amit elveszíthetne, így eltávolíthatja a try-catch blokkot, és meghagyhatja a sort, amely megsemmisíti a modult (await module.DisposeAsync();). További információ: ASP.NET Core Blazor JavaScript-együttműködés (JS interop).

CallDotNetExampleOneHelper.razor.js:

export class GreetingHelpers {
  static dotNetHelper;

  static setDotNetHelper(value) {
    GreetingHelpers.dotNetHelper = value;
  }

  static async sayHello() {
    const msg =
      await GreetingHelpers.dotNetHelper.invokeMethodAsync('GetHelloMessage');
    alert(`Message from .NET: "${msg}"`);
  }

  static async welcomeVisitor() {
    const msg =
      await GreetingHelpers.dotNetHelper.invokeMethodAsync('GetWelcomeMessage');
    alert(`Message from .NET: "${msg}"`);
  }
}

export function addHandlers() {
  const sayHelloBtn = document.getElementById("sayHelloBtn");
  sayHelloBtn.addEventListener("click", GreetingHelpers.sayHello);

  const welcomeVisitorBtn = document.getElementById("welcomeVisitorBtn");
  welcomeVisitorBtn.addEventListener("click", GreetingHelpers.welcomeVisitor);
}

Az előző példában a változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.

@page "/call-dotnet-example-one-helper"
@implements IDisposable
@inject IJSRuntime JS

<h1>Pass <code>DotNetObjectReference</code> to a JavaScript class</h1>

<p>
    <label>
        Message: <input @bind="name" />
    </label>
</p>

<p>
    <button onclick="GreetingHelpers.sayHello()">
        Trigger JS function <code>sayHello</code>
    </button>
</p>

<p>
    <button onclick="GreetingHelpers.welcomeVisitor()">
        Trigger JS function <code>welcomeVisitor</code>
    </button>
</p>

@code {
    private string? name;
    private DotNetObjectReference<CallDotNetExampleOneHelper>? dotNetHelper;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            dotNetHelper = DotNetObjectReference.Create(this);
            await JS.InvokeVoidAsync("GreetingHelpers.setDotNetHelper", 
                dotNetHelper);
        }
    }

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {name}!";

    [JSInvokable]
    public string GetWelcomeMessage() => $"Welcome, {name}!";

    public void Dispose()
    {
        dotNetHelper?.Dispose();
    }
}

Az előző példában:

  • JS egy injektált IJSRuntime példány. A IJSRuntime-t a Blazor keretrendszer regisztrálja.
  • A változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.
  • Az összetevőnek explicit módon el kell végeznie a DotNetObjectReference szemétgyűjtést, és meg kell akadályoznia a memóriaszivárgást.
<script>
  class GreetingHelpers {
    static dotNetHelper;

    static setDotNetHelper(value) {
      GreetingHelpers.dotNetHelper = value;
    }

    static async sayHello() {
      const msg = 
        await GreetingHelpers.dotNetHelper.invokeMethodAsync('GetHelloMessage');
      alert(`Message from .NET: "${msg}"`);
    }

    static async welcomeVisitor() {
      const msg = 
        await GreetingHelpers.dotNetHelper.invokeMethodAsync('GetWelcomeMessage');
      alert(`Message from .NET: "${msg}"`);
    }
  }

  window.GreetingHelpers = GreetingHelpers;
</script>

Az előző példában:

  • A GreetingHelpers osztály hozzáadódik az window objektumhoz, hogy globálisan definiálja az osztályt, amely lehetővé teszi Blazor-nak az osztály megkeresését az JS interop során.
  • A változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.

Note

A JS helyére és az éles alkalmazásokkal kapcsolatos ajánlásainkra vonatkozó általános útmutatásért nézze meg a JavaScript-helyet az ASP.NET Core Blazor alkalmazásokban.

Általános .NET-osztály metódusok meghívása

A JavaScript (JS) függvények meghívhatják a .NET általános osztály metódusait, ahol egy JS függvény egy általános osztály .NET-metódusát hívja meg.

A következő általános típusosztályban (GenericType<TValue>):

  • Az osztály egyetlen típusparaméterrel (TValue) rendelkezik egyetlen általános Value tulajdonsággal.
  • Az osztály két nem általános metódust jelölt meg az [JSInvokable] attribútummal, mindegyikhez tartozik egy általános típusparaméter neve newValue:
    • Update szinkron módon frissíti a Value értékét a newValue alapján.
    • UpdateAsync aszinkron módon frissíti a Value értékét a newValue-ben, miután létrehozza a Task.Yield várható feladatot, amely aszinkron módon visszatér a jelenlegi környezetbe, amikor az várakozik.
  • Az osztály metódusai a konzolra írják a típust TValue és az értéket Value . A konzolra való írás csak bemutató célokra használható. Az éles alkalmazások általában nem írnak a konzolra az alkalmazásnaplózás helyett. További információért lásd: Blazor és NAPLÓZÁS A .NET ÉS ASP.NET Core RENDSZEREKBEN.

Note

A nyitott általános típusok és metódusok nem adnak meg típushelyőrzőket. Ezzel szemben a zárt generikusok minden típushelyőrzőhöz biztosítanak típustípusokat. Az ebben a szakaszban szereplő példák a zárt generikusokat mutatják be, de JS az interop instance metódusok meghívása nyílt generikusokkal támogatott. A nyílt generikusok használata nem támogatott statikus .NET-metódushívásokhoz, amelyeket a cikk korábbi részében ismertettünk.

További információkért lásd a következő cikkeket:

GenericType.cs:

using Microsoft.JSInterop;

public class GenericType<TValue>
{
    public TValue? Value { get; set; }

    [JSInvokable]
    public void Update(TValue newValue)
    {
        Value = newValue;

        Console.WriteLine($"Update: GenericType<{typeof(TValue)}>: {Value}");
    }

    [JSInvokable]
    public async Task UpdateAsync(TValue newValue)
    {
        await Task.Yield();
        Value = newValue;

        Console.WriteLine($"UpdateAsync: GenericType<{typeof(TValue)}>: {Value}");
    }
}

A következő invokeMethodsAsync függvényben:

  • Az általános típusosztályok Update és UpdateAsync metódusok sztringeket és számokat jelölő argumentumokkal vannak meghívva.
  • Az ügyféloldali összetevők támogatják a .NET-metódusok szinkron hívását.invokeMethod syncInterop logikai értéket kap, amely jelzi, hogy az JS interop az ügyfélen történik-e. Amikor syncInterop van true, invokeMethod biztonságosan meghívható. Ha az érték syncInterop az false, a rendszer csak az aszinkron függvényt invokeMethodAsync hívja meg, mert az JS interop egy kiszolgálóoldali összetevőben fut.
  • Bemutató célokra a DotNetObjectReference függvényhívás (invokeMethod vagy invokeMethodAsync), a .NET metódus neve (Update vagy UpdateAsync) és az argumentum a konzolra lesz írva. Az argumentumok véletlenszerű szám használatával teszik lehetővé a JS függvényhívásnak a .NET metódushíváshoz való egyeztetését (a .NET oldalán lévő konzolra is írva). A gyártási kód általában nem ír ki a konzolra, sem az ügyfélen, sem a kiszolgálón. Az éles alkalmazások általában alkalmazásnaplózásra támaszkodnak. További információért lásd: Blazor és NAPLÓZÁS A .NET ÉS ASP.NET Core RENDSZEREKBEN.
<script>
  const randomInt = () => Math.floor(Math.random() * 99999);

  window.invokeMethodsAsync = async (syncInterop, dotNetHelper1, dotNetHelper2) => {
    var n = randomInt();
    console.log(`JS: invokeMethodAsync:Update('string ${n}')`);
    await dotNetHelper1.invokeMethodAsync('Update', `string ${n}`);

    n = randomInt();
    console.log(`JS: invokeMethodAsync:UpdateAsync('string ${n}')`);
    await dotNetHelper1.invokeMethodAsync('UpdateAsync', `string ${n}`);

    if (syncInterop) {
      n = randomInt();
      console.log(`JS: invokeMethod:Update('string ${n}')`);
      dotNetHelper1.invokeMethod('Update', `string ${n}`);
    }

    n = randomInt();
    console.log(`JS: invokeMethodAsync:Update(${n})`);
    await dotNetHelper2.invokeMethodAsync('Update', n);

    n = randomInt();
    console.log(`JS: invokeMethodAsync:UpdateAsync(${n})`);
    await dotNetHelper2.invokeMethodAsync('UpdateAsync', n);

    if (syncInterop) {
      n = randomInt();
      console.log(`JS: invokeMethod:Update(${n})`);
      dotNetHelper2.invokeMethod('Update', n);
    }
  };
</script>

Note

A JS helyére és az éles alkalmazásokkal kapcsolatos ajánlásainkra vonatkozó általános útmutatásért nézze meg a JavaScript-helyet az ASP.NET Core Blazor alkalmazásokban.

Az alábbi GenericsExample összetevőben:

  • A JS függvény invokeMethodsAsync akkor lesz meghívva, amikor a gombot Invoke Interop kiválasztják.
  • A rendszer létrehoz egy típuspárt DotNetObjectReference, és átadja az JS függvénynek az GenericType példányaihoz string-ként és int-ként.

GenericsExample.razor:

@page "/generics-example"
@implements IDisposable
@inject IJSRuntime JS

<p>
    <button @onclick="InvokeInterop">Invoke Interop</button>
</p>

<ul>
    <li>genericType1: @genericType1?.Value</li>
    <li>genericType2: @genericType2?.Value</li>
</ul>

@code {
    private GenericType<string> genericType1 = new() { Value = "string 0" };
    private GenericType<int> genericType2 = new() { Value = 0 };
    private DotNetObjectReference<GenericType<string>>? objRef1;
    private DotNetObjectReference<GenericType<int>>? objRef2;

    protected override void OnInitialized()
    {
        objRef1 = DotNetObjectReference.Create(genericType1);
        objRef2 = DotNetObjectReference.Create(genericType2);
    }

    public async Task InvokeInterop()
    {
        var syncInterop = OperatingSystem.IsBrowser();

        await JS.InvokeVoidAsync(
            "invokeMethodsAsync", syncInterop, objRef1, objRef2);
    }

    public void Dispose()
    {
        objRef1?.Dispose();
        objRef2?.Dispose();
    }
}
@page "/generics-example"
@implements IDisposable
@inject IJSRuntime JS

<p>
    <button @onclick="InvokeInterop">Invoke Interop</button>
</p>

<ul>
    <li>genericType1: @genericType1?.Value</li>
    <li>genericType2: @genericType2?.Value</li>
</ul>

@code {
    private GenericType<string> genericType1 = new() { Value = "string 0" };
    private GenericType<int> genericType2 = new() { Value = 0 };
    private DotNetObjectReference<GenericType<string>>? objRef1;
    private DotNetObjectReference<GenericType<int>>? objRef2;

    protected override void OnInitialized()
    {
        objRef1 = DotNetObjectReference.Create(genericType1);
        objRef2 = DotNetObjectReference.Create(genericType2);
    }

    public async Task InvokeInterop()
    {
        var syncInterop = OperatingSystem.IsBrowser();

        await JS.InvokeVoidAsync(
            "invokeMethodsAsync", syncInterop, objRef1, objRef2);
    }

    public void Dispose()
    {
        objRef1?.Dispose();
        objRef2?.Dispose();
    }
}

Az előző példában JS egy injektált IJSRuntime példány. A IJSRuntime-t a Blazor keretrendszer regisztrálja.

Az alábbi ábra az előző példa jellemző kimenetét mutatja be, amikor a Invoke Interop gombot egy ügyféloldali összetevőben választja ki:

JS: invokeMethodAsync:Update('string 37802')
.NET: Frissítés: GenericType<System.String>: string 37802
JS: invokeMethodAsync:UpdateAsync('string 53051')
JS: invokeMethod:Update('string 26784')
.NET: Frissítés: GenericType<System.String>: string 26784
JS: invokeMethodAsync:Update(14107)
.NET: Frissítés: GenericType<System.Int32>: 14107
JS: invokeMethodAsync:UpdateAsync(48995)
JS: invokeMethod:Update(12872)
.NET: Frissítés: GenericType<System.Int32>: 12872
.NET: UpdateAsync: GenericType<System.String>: string 53051
.NET: UpdateAsync: GenericType<System.Int32>: 48995

Ha az előző példa egy kiszolgálóoldali összetevőben van implementálva, a szinkron hívások invokeMethod elkerülhetők. Kiszolgálóoldali összetevők esetén az aszinkron függvényt (invokeMethodAsync) javasoljuk a szinkron verzió (invokeMethod) felett.

Kiszolgálóoldali összetevő jellemző kimenete:

JS: invokeMethodAsync:Update('string 34809')
.NET: Frissítés: GenericType<System.String>: string 34809
JS: invokeMethodAsync:UpdateAsync('string 93059')
JS: invokeMethodAsync:Update(41997)
.NET: Frissítés: GenericType<System.Int32>: 41997
JS: invokeMethodAsync:UpdateAsync(24652)
.NET: UpdateAsync: GenericType<System.String>: karakterlánc 93059
.NET: UpdateAsync: GenericType<System.Int32>: 24652

Az előző kimeneti példák azt mutatják, hogy az aszinkron metódusok különböző tényezőktől függően tetszőleges sorrendben hajtódnak végre és teljesülnek, beleértve a szálütemezést és a metódus végrehajtásának sebességét. Az aszinkron metódushívások befejezési sorrendjének megbízható előrejelzése nem lehetséges.

Osztálypéldány példák

A következő sayHello1JS függvény:

  • Meghívja a GetHelloMessage .NET metódust az átadott DotNetObjectReference.
  • Visszaadja az üzenetet a GetHelloMessage hívónaksayHello1.
<script>
  window.sayHello1 = (dotNetHelper) => {
    return dotNetHelper.invokeMethodAsync('GetHelloMessage');
  };
</script>

Note

A JS helyére és az éles alkalmazásokkal kapcsolatos ajánlásainkra vonatkozó általános útmutatásért nézze meg a JavaScript-helyet az ASP.NET Core Blazor alkalmazásokban.

Az előző példában a változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.

Az alábbi HelloHelper osztály rendelkezik egy JS-ként meghívható .NET metódussal, amelynek neve GetHelloMessage. Amikor HelloHelper létrejön, a Name tulajdonságban lévő névvel egy üzenetet ad vissza a rendszer a GetHelloMessage-ből.

HelloHelper.cs:

using Microsoft.JSInterop;

namespace BlazorSample;

public class HelloHelper(string? name)
{
    public string? Name { get; set; } = name ?? "No Name";

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {Name}!";
}
using Microsoft.JSInterop;

namespace BlazorSample;

public class HelloHelper(string? name)
{
    public string? Name { get; set; } = name ?? "No Name";

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {Name}!";
}
using Microsoft.JSInterop;

public class HelloHelper
{
    public HelloHelper(string? name)
    {
        Name = name ?? "No Name";
    }

    public string? Name { get; set; }

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {Name}!";
}
using Microsoft.JSInterop;

public class HelloHelper
{
    public HelloHelper(string? name)
    {
        Name = name ?? "No Name";
    }

    public string? Name { get; set; }

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {Name}!";
}
using Microsoft.JSInterop;

public class HelloHelper
{
    public HelloHelper(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {Name}!";
}
using Microsoft.JSInterop;

public class HelloHelper
{
    public HelloHelper(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

    [JSInvokable]
    public string GetHelloMessage() => $"Hello, {Name}!";
}

A következő CallHelloHelperGetHelloMessage osztály JsInteropClasses3 metódusa meghívja a JS függvényt sayHello1 egy új HelloHelper példányával.

JsInteropClasses3.cs:

using Microsoft.JSInterop;

namespace BlazorSample;

public class JsInteropClasses3(IJSRuntime js)
{
    private readonly IJSRuntime js = js;

    public async ValueTask<string> CallHelloHelperGetHelloMessage(string? name)
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        return await js.InvokeAsync<string>("sayHello1", objRef);
    }
}
using Microsoft.JSInterop;

namespace BlazorSample;

public class JsInteropClasses3(IJSRuntime js)
{
    private readonly IJSRuntime js = js;

    public async ValueTask<string> CallHelloHelperGetHelloMessage(string? name)
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        return await js.InvokeAsync<string>("sayHello1", objRef);
    }
}
using Microsoft.JSInterop;

public class JsInteropClasses3
{
    private readonly IJSRuntime js;

    public JsInteropClasses3(IJSRuntime js)
    {
        this.js = js;
    }

    public async ValueTask<string> CallHelloHelperGetHelloMessage(string? name)
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        return await js.InvokeAsync<string>("sayHello1", objRef);
    }
}
using Microsoft.JSInterop;

public class JsInteropClasses3
{
    private readonly IJSRuntime js;

    public JsInteropClasses3(IJSRuntime js)
    {
        this.js = js;
    }

    public async ValueTask<string> CallHelloHelperGetHelloMessage(string? name)
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        return await js.InvokeAsync<string>("sayHello1", objRef);
    }
}
using System.Threading.Tasks;
using Microsoft.JSInterop;

public class JsInteropClasses3
{
    private readonly IJSRuntime js;

    public JsInteropClasses3(IJSRuntime js)
    {
        this.js = js;
    }

    public async ValueTask<string> CallHelloHelperGetHelloMessage(string name)
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        return await js.InvokeAsync<string>("sayHello1", objRef);
    }
}
using System.Threading.Tasks;
using Microsoft.JSInterop;

public class JsInteropClasses3
{
    private readonly IJSRuntime js;

    public JsInteropClasses3(IJSRuntime js)
    {
        this.js = js;
    }

    public async ValueTask<string> CallHelloHelperGetHelloMessage(string name)
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        return await js.InvokeAsync<string>("sayHello1", objRef);
    }
}

A memóriaszivárgás elkerülése és a szemétgyűjtés engedélyezése érdekében a létrehozott .NET-objektumhivatkozást DotNetObjectReference töröljük, amikor az objektumhivatkozás a using var szintaxissal kilép a hatókörből.

Ha a Trigger .NET instance method gombot választják ki a következő összetevőben, a JsInteropClasses3.CallHelloHelperGetHelloMessage függvényt meghívják a name értékkel.

CallDotnet4.razor:

@page "/call-dotnet-4"
@inject IJSRuntime JS

<PageTitle>Call .NET 4</PageTitle>

<h1>Call .NET Example 4</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private JsInteropClasses3? jsInteropClasses;

    protected override void OnInitialized() => 
        jsInteropClasses = new JsInteropClasses3(JS);

    private async Task TriggerDotNetInstanceMethod()
    {
        if (jsInteropClasses is not null)
        {
            result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
        }
    }
}

CallDotnet4.razor:

@page "/call-dotnet-4"
@inject IJSRuntime JS

<PageTitle>Call .NET 4</PageTitle>

<h1>Call .NET Example 4</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private JsInteropClasses3? jsInteropClasses;

    protected override void OnInitialized() => 
        jsInteropClasses = new JsInteropClasses3(JS);

    private async Task TriggerDotNetInstanceMethod()
    {
        if (jsInteropClasses is not null)
        {
            result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
        }
    }
}

CallDotNetExample4.razor:

@page "/call-dotnet-example-4"
@inject IJSRuntime JS

<h1>Call .NET Example 4</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private JsInteropClasses3? jsInteropClasses;

    protected override void OnInitialized()
    {
        jsInteropClasses = new JsInteropClasses3(JS);
    }

    private async Task TriggerDotNetInstanceMethod()
    {
        if (jsInteropClasses is not null)
        {
            result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
        }
    }
}

CallDotNetExample4.razor:

@page "/call-dotnet-example-4"
@inject IJSRuntime JS

<h1>Call .NET Example 4</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;
    private JsInteropClasses3? jsInteropClasses;

    protected override void OnInitialized()
    {
        jsInteropClasses = new JsInteropClasses3(JS);
    }

    private async Task TriggerDotNetInstanceMethod()
    {
        if (jsInteropClasses is not null)
        {
            result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
        }
    }
}

CallDotNetExample4.razor:

@page "/call-dotnet-example-4"
@inject IJSRuntime JS

<h1>Call .NET Example 4</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string name;
    private string result;
    private JsInteropClasses3 jsInteropClasses;

    protected override void OnInitialized()
    {
        jsInteropClasses = new JsInteropClasses3(JS);
    }

    private async Task TriggerDotNetInstanceMethod()
    {
        result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
    }
}

CallDotNetExample4.razor:

@page "/call-dotnet-example-4"
@inject IJSRuntime JS

<h1>Call .NET Example 4</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string name;
    private string result;
    private JsInteropClasses3 jsInteropClasses;

    protected override void OnInitialized()
    {
        jsInteropClasses = new JsInteropClasses3(JS);
    }

    private async Task TriggerDotNetInstanceMethod()
    {
        result = await jsInteropClasses.CallHelloHelperGetHelloMessage(name);
    }
}

Az alábbi képen a Amy Pond mezőben látható a Name nevű renderelt összetevő. A gomb kiválasztása Hello, Amy Pond! után megjelenik a felhasználói felületen:

Renderelt

Az osztályban JsInteropClasses3 látható előző minta teljes egészében implementálható egy összetevőben is.

CallDotnet5.razor:

@page "/call-dotnet-5"
@inject IJSRuntime JS

<PageTitle>Call .NET 5</PageTitle>

<h1>Call .NET Example 5</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;

    public async Task TriggerDotNetInstanceMethod()
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        result = await JS.InvokeAsync<string>("sayHello1", objRef);
    }
}

CallDotnet5.razor:

@page "/call-dotnet-5"
@inject IJSRuntime JS

<PageTitle>Call .NET 5</PageTitle>

<h1>Call .NET Example 5</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;

    public async Task TriggerDotNetInstanceMethod()
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        result = await JS.InvokeAsync<string>("sayHello1", objRef);
    }
}

CallDotNetExample5.razor:

@page "/call-dotnet-example-5"
@inject IJSRuntime JS

<h1>Call .NET Example 5</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;

    public async Task TriggerDotNetInstanceMethod()
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        result = await JS.InvokeAsync<string>("sayHello1", objRef);
    }
}

CallDotNetExample5.razor:

@page "/call-dotnet-example-5"
@inject IJSRuntime JS

<h1>Call .NET Example 5</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string? name;
    private string? result;

    public async Task TriggerDotNetInstanceMethod()
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        result = await JS.InvokeAsync<string>("sayHello1", objRef);
    }
}

CallDotNetExample5.razor:

@page "/call-dotnet-example-5"
@inject IJSRuntime JS

<h1>Call .NET Example 5</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string name;
    private string result;

    public async Task TriggerDotNetInstanceMethod()
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        result = await JS.InvokeAsync<string>("sayHello1", objRef);
    }
}

CallDotNetExample5.razor:

@page "/call-dotnet-example-5"
@inject IJSRuntime JS

<h1>Call .NET Example 5</h1>

<p>
    <label>
        Name: <input @bind="name" />
    </label>
</p>

<p>
    <button @onclick="TriggerDotNetInstanceMethod">
        Trigger .NET instance method
    </button>
</p>

<p>
    @result
</p>

@code {
    private string name;
    private string result;

    public async Task TriggerDotNetInstanceMethod()
    {
        using var objRef = DotNetObjectReference.Create(new HelloHelper(name));
        result = await JS.InvokeAsync<string>("sayHello1", objRef);
    }
}

A memóriaszivárgás elkerülése és a szemétgyűjtés engedélyezése érdekében a létrehozott .NET-objektumhivatkozást DotNetObjectReference töröljük, amikor az objektumhivatkozás a using var szintaxissal kilép a hatókörből.

Az összetevő által megjelenített kimenet az Hello, Amy Pond! , amikor a név Amy Pond meg van adva a name mezőben.

Az előző összetevőben a .NET-objektumhivatkozás el lesz osztva. Ha egy osztály vagy komponens nem szabadítja fel a DotNetObjectReference, akkor az ügyfélen keresztül a megadott dispose hívásával a DotNetObjectReference kezelő funkciót alkalmazva felszabadíthatja azt.

window.{JS FUNCTION NAME} = (dotNetHelper) => {
  dotNetHelper.invokeMethodAsync('{.NET METHOD ID}');
  dotNetHelper.dispose();
}

Az előző példában:

  • A {JS FUNCTION NAME} helyőrző a JS függvény neve.
  • A változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.
  • A {.NET METHOD ID} helyőrző a .NET metódusazonosító.

Komponenspéldány .NET-metódusokhoz tartozó segédosztály

A segédosztály meghívhat egy .NET-példány metódust Action. A segédosztályok olyan helyzetekben hasznosak, amikor a statikus .NET-metódusok nem alkalmazhatók:

  • Ha több azonos típusú összetevő jelenik meg ugyanazon a lapon.
  • Kiszolgálóoldali alkalmazásokban, amelyek több felhasználóval egyidejűleg ugyanazt az összetevőt használják.

Az alábbi példában:

  • Az összetevő több ListItem1 összetevőt tartalmaz.
  • Minden ListItem1 összetevő egy üzenetből és egy gombból áll.
  • Amikor kiválasztják a ListItem1 típusú komponens gombját, az a ListItem1 metódus módosítja a UpdateMessage listaelem szövegét, és elrejti a gombot.

Az alábbi MessageUpdateInvokeHelper osztály egy JS-invokable .NET metódust tart fenn, UpdateMessageCaller amely az osztály példányosításakor megadott Action-t hívja meg.

MessageUpdateInvokeHelper.cs:

using Microsoft.JSInterop;

namespace BlazorSample;

public class MessageUpdateInvokeHelper(Action action)
{
    private readonly Action action = action;

    [JSInvokable]
    public void UpdateMessageCaller() => action.Invoke();
}
using Microsoft.JSInterop;

namespace BlazorSample;

public class MessageUpdateInvokeHelper(Action action)
{
    private readonly Action action = action;

    [JSInvokable]
    public void UpdateMessageCaller() => action.Invoke();
}
using Microsoft.JSInterop;

public class MessageUpdateInvokeHelper
{
    private Action action;

    public MessageUpdateInvokeHelper(Action action)
    {
        this.action = action;
    }

    [JSInvokable]
    public void UpdateMessageCaller()
    {
        action.Invoke();
    }
}
using Microsoft.JSInterop;

public class MessageUpdateInvokeHelper
{
    private Action action;

    public MessageUpdateInvokeHelper(Action action)
    {
        this.action = action;
    }

    [JSInvokable]
    public void UpdateMessageCaller()
    {
        action.Invoke();
    }
}
using System;
using Microsoft.JSInterop;

public class MessageUpdateInvokeHelper
{
    private Action action;

    public MessageUpdateInvokeHelper(Action action)
    {
        this.action = action;
    }

    [JSInvokable]
    public void UpdateMessageCaller()
    {
        action.Invoke();
    }
}
using System;
using Microsoft.JSInterop;

public class MessageUpdateInvokeHelper
{
    private Action action;

    public MessageUpdateInvokeHelper(Action action)
    {
        this.action = action;
    }

    [JSInvokable]
    public void UpdateMessageCaller()
    {
        action.Invoke();
    }
}

Az alábbi updateMessageCallerJS függvény meghívja a UpdateMessageCaller .NET metódust.

<script>
  window.updateMessageCaller = (dotNetHelper) => {
    dotNetHelper.invokeMethodAsync('UpdateMessageCaller');
    dotNetHelper.dispose();
  }
</script>

Note

A JS helyére és az éles alkalmazásokkal kapcsolatos ajánlásainkra vonatkozó általános útmutatásért nézze meg a JavaScript-helyet az ASP.NET Core Blazor alkalmazásokban.

Az előző példában a változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.

A következő ListItem1 összetevő egy megosztott összetevő, amely tetszőleges számú alkalommal használható egy szülőösszetevőben, és listaelemeket (<li>...</li>) hoz létre egy HTML-lista (<ul>...</ul> vagy <ol>...</ol>). Minden ListItem1 összetevőpéldány létrehoz egy MessageUpdateInvokeHelper példányt, amelynek Action a UpdateMessage metódushoz van beállítva.

Amikor egy ListItem1 komponens InteropCall gombja ki van választva, meghívásra kerül updateMessageCaller egy létrehozott DotNetObjectReference, amely a(z) MessageUpdateInvokeHelper példányhoz tartozik. Ez lehetővé teszi a keretrendszernek, hogy meghívja a UpdateMessageCallerListItem1 példányának MessageUpdateInvokeHelper-jét. Az átadott DotNetObjectReference megsemmisítésre kerül JS-ban (dotNetHelper.dispose()).

ListItem1.razor:

@inject IJSRuntime JS

<li>
    @message
    <button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>

@code {
    private string message = "Select one of these list item buttons.";
    private string display = "inline-block";
    private MessageUpdateInvokeHelper? messageUpdateInvokeHelper;

    protected override void OnInitialized()
    {
        messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
    }

    protected async Task InteropCall()
    {
        if (messageUpdateInvokeHelper is not null)
        {
            await JS.InvokeVoidAsync("updateMessageCaller",
                DotNetObjectReference.Create(messageUpdateInvokeHelper));
        }
    }

    private void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        StateHasChanged();
    }
}
@inject IJSRuntime JS

<li>
    @message
    <button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>

@code {
    private string message = "Select one of these list item buttons.";
    private string display = "inline-block";
    private MessageUpdateInvokeHelper? messageUpdateInvokeHelper;

    protected override void OnInitialized()
    {
        messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
    }

    protected async Task InteropCall()
    {
        if (messageUpdateInvokeHelper is not null)
        {
            await JS.InvokeVoidAsync("updateMessageCaller",
                DotNetObjectReference.Create(messageUpdateInvokeHelper));
        }
    }

    private void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        StateHasChanged();
    }
}
@inject IJSRuntime JS

<li>
    @message
    <button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>

@code {
    private string message = "Select one of these list item buttons.";
    private string display = "inline-block";
    private MessageUpdateInvokeHelper? messageUpdateInvokeHelper;

    protected override void OnInitialized()
    {
        messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
    }

    protected async Task InteropCall()
    {
        if (messageUpdateInvokeHelper is not null)
        {
            await JS.InvokeVoidAsync("updateMessageCaller",
                DotNetObjectReference.Create(messageUpdateInvokeHelper));
        }
    }

    private void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        StateHasChanged();
    }
}
@inject IJSRuntime JS

<li>
    @message
    <button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>

@code {
    private string message = "Select one of these list item buttons.";
    private string display = "inline-block";
    private MessageUpdateInvokeHelper? messageUpdateInvokeHelper;

    protected override void OnInitialized()
    {
        messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
    }

    protected async Task InteropCall()
    {
        if (messageUpdateInvokeHelper is not null)
        {
            await JS.InvokeVoidAsync("updateMessageCaller",
                DotNetObjectReference.Create(messageUpdateInvokeHelper));
        }
    }

    private void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        StateHasChanged();
    }
}
@inject IJSRuntime JS

<li>
    @message
    <button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>

@code {
    private string message = "Select one of these list item buttons.";
    private string display = "inline-block";
    private MessageUpdateInvokeHelper messageUpdateInvokeHelper;

    protected override void OnInitialized()
    {
        messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
    }

    protected async Task InteropCall()
    {
        await JS.InvokeVoidAsync("updateMessageCaller",
            DotNetObjectReference.Create(messageUpdateInvokeHelper));
    }

    private void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        StateHasChanged();
    }
}
@inject IJSRuntime JS

<li>
    @message
    <button @onclick="InteropCall" style="display:@display">InteropCall</button>
</li>

@code {
    private string message = "Select one of these list item buttons.";
    private string display = "inline-block";
    private MessageUpdateInvokeHelper messageUpdateInvokeHelper;

    protected override void OnInitialized()
    {
        messageUpdateInvokeHelper = new MessageUpdateInvokeHelper(UpdateMessage);
    }

    protected async Task InteropCall()
    {
        await JS.InvokeVoidAsync("updateMessageCaller",
            DotNetObjectReference.Create(messageUpdateInvokeHelper));
    }

    private void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        StateHasChanged();
    }
}

StateHasChanged a rendszer meghívja a felhasználói felület frissítésére, amikor message be van állítva a UpdateMessage. Ha a StateHasChanged nincs meghívva, Blazor nem tudja, hogy frissíteni kell a felhasználói felületet, amikor a Action meghívásra kerül.

A következő szülőösszetevő négy listaelemet tartalmaz, amelyek mindegyike az ListItem1 összetevő egy-egy példánya.

CallDotnet6.razor:

@page "/call-dotnet-6"

<PageTitle>Call .NET 6</PageTitle>

<h1>Call .NET Example 6</h1>

<ul>
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
</ul>

CallDotnet6.razor:

@page "/call-dotnet-6"

<PageTitle>Call .NET 6</PageTitle>

<h1>Call .NET Example 6</h1>

<ul>
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
</ul>

CallDotNetExample6.razor:

@page "/call-dotnet-example-6"

<h1>Call .NET Example 6</h1>

<ul>
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
</ul>

CallDotNetExample6.razor:

@page "/call-dotnet-example-6"

<h1>Call .NET Example 6</h1>

<ul>
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
</ul>

CallDotNetExample6.razor:

@page "/call-dotnet-example-6"

<h1>Call .NET Example 6</h1>

<ul>
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
</ul>

CallDotNetExample6.razor:

@page "/call-dotnet-example-6"

<h1>Call .NET Example 6</h1>

<ul>
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
    <ListItem1 />
</ul>

Az alábbi képen a renderelt szülőösszetevő látható a második InteropCall gomb kiválasztása után:

  • A második ListItem1 összetevő megjeleníti az UpdateMessage Called! üzenetet.
  • A második InteropCall összetevő ListItem1 gombja nem látható, mert a gomb display CSS-tulajdonsága be van állítva none.

Renderelt

Elemtulajdonsághoz rendelt összetevőpéldány .NET metódusa DotNetObjectReference

Egy HTML-elem tulajdonságához való hozzárendelés DotNetObjectReference lehetővé teszi a .NET-metódusok meghívását egy összetevőpéldányon:

A Komponenspéldány .NET metódus segédosztályában ismertetett megközelítéshez hasonlóan ez a megközelítés olyan esetekben hasznos, amikor a statikus .NET-metódusok nem alkalmazhatók:

  • Ha több azonos típusú összetevő jelenik meg ugyanazon a lapon.
  • Kiszolgálóoldali alkalmazásokban, amelyek több felhasználóval egyidejűleg ugyanazt az összetevőt használják.
  • A .NET metódus meghívása eseményből JS történik (például onclick), nem eseményből Blazor (például @onclick).

Az alábbi példában:

  • Az összetevő több ListItem2 összetevőt tartalmaz, amely egy megosztott összetevő.
  • Minden ListItem2 összetevő egy listaelem-üzenetből <span> és egy második <span> elemből áll, amelynél a display CSS-tulajdonság inline-block módon van beállítva a megjelenítés céljából.
  • Ha egy ListItem2 összetevőlistaelem van kijelölve, akkor a ListItem2UpdateMessage metódusa módosítja a listaelem szövegét az első <span>-ban, és elrejti a második <span>-t úgy, hogy beállítja annak display tulajdonságát a none értékre.

Az alábbi assignDotNetHelperJS függvény hozzárendeli a DotNetObjectReference-t egy dotNetHelper nevű tulajdonság egyik eleméhez. Az alábbi interopCallJS függvény a DotNetObjectReference az átadott elemhez használja, hogy meghívjon egy .NET metódust UpdateMessage névvel.

ListItem2.razor.js:

export function assignDotNetHelper(element, dotNetHelper) {
  element.dotNetHelper = dotNetHelper;
}

export async function interopCall(element) {
  await element.dotNetHelper.invokeMethodAsync('UpdateMessage');
}

ListItem2.razor.js:

export function assignDotNetHelper(element, dotNetHelper) {
  element.dotNetHelper = dotNetHelper;
}

export async function interopCall(element) {
  await element.dotNetHelper.invokeMethodAsync('UpdateMessage');
}
<script>
  window.assignDotNetHelper = (element, dotNetHelper) => {
    element.dotNetHelper = dotNetHelper;
  }

  window.interopCall = async (element) => {
    await element.dotNetHelper.invokeMethodAsync('UpdateMessage');
  }
</script>

Note

A JS helyére és az éles alkalmazásokkal kapcsolatos ajánlásainkra vonatkozó általános útmutatásért nézze meg a JavaScript-helyet az ASP.NET Core Blazor alkalmazásokban.

Az előző példában a változó neve dotNetHelper tetszőleges, és bármely előnyben részesített névre módosítható.

A következő ListItem2 összetevő egy megosztott összetevő, amely tetszőleges számú alkalommal használható egy szülőösszetevőben, és listaelemeket (<li>...</li>) hoz létre egy HTML-lista (<ul>...</ul> vagy <ol>...</ol>).

Minden ListItem2 összetevőpéldány meghívja a assignDotNetHelper található JSOnAfterRenderAsync függvényt egy elemhivatkozással (a listaelem első <span> eleme), és összetevőpéldányként szerepel mint DotNetObjectReference.

Ha egy ListItem2 összetevő üzenete <span> ki van választva, interopCall hívódik meg, ami paraméterként megkapja az <span> elemet (this), és amely meghívja a UpdateMessage .NET metódust. A UpdateMessage belül meghívják a StateHasChanged-t a felhasználói felület frissítésére, amikor message be van állítva, és a második display<span> tulajdonsága frissül. Ha StateHasChanged nincs meghívva, Blazor nem tudja, hogy a felhasználói felületet frissíteni kell a metódus meghívásakor.

A DotNetObjectReference ártalmatlanná válik, amikor az összetevő ártalmatlanítva van.

ListItem2.razor:

@inject IJSRuntime JS
@implements IAsyncDisposable

<li>
    <span style="font-weight:bold;color:@color" @ref="elementRef"
        @onclick="CallJSToInvokeDotnet">
        @message
    </span>
    <span style="display:@display">
        Not Updated Yet!
    </span>
</li>

@code {
    private IJSObjectReference? module;
    private DotNetObjectReference<ListItem2>? objRef;
    private ElementReference elementRef;
    private string display = "inline-block";
    private string message = "Select one of these list items.";
    private string color = "initial";

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            module = await JS.InvokeAsync<IJSObjectReference>("import",
                "./Components/ListItem2.razor.js");

            objRef = DotNetObjectReference.Create(this);
            await module.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
        }
    }

    public async Task CallJSToInvokeDotnet()
    {
        if (module is not null)
        {
            await module.InvokeVoidAsync("interopCall", elementRef);
        }
    }

    [JSInvokable]
    public void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        color = "MediumSeaGreen";
        StateHasChanged();
    }

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
        {
            try
            {
                await module.DisposeAsync();
            }
            catch (JSDisconnectedException)
            {
            }
        }

        objRef?.Dispose();
    }
}
@inject IJSRuntime JS
@implements IAsyncDisposable

<li>
    <span style="font-weight:bold;color:@color" @ref="elementRef"
        @onclick="CallJSToInvokeDotnet">
        @message
    </span>
    <span style="display:@display">
        Not Updated Yet!
    </span>
</li>

@code {
    private IJSObjectReference? module;
    private DotNetObjectReference<ListItem2>? objRef;
    private ElementReference elementRef;
    private string display = "inline-block";
    private string message = "Select one of these list items.";
    private string color = "initial";

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            module = await JS.InvokeAsync<IJSObjectReference>("import",
                "./Components/ListItem2.razor.js");

            objRef = DotNetObjectReference.Create(this);
            await module.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
        }
    }

    public async Task CallJSToInvokeDotnet()
    {
        if (module is not null)
        {
            await module.InvokeVoidAsync("interopCall", elementRef);
        }
    }

    [JSInvokable]
    public void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        color = "MediumSeaGreen";
        StateHasChanged();
    }

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
        {
            try
            {
                await module.DisposeAsync();
            }
            catch (JSDisconnectedException)
            {
            }
        }

        objRef?.Dispose();
    }
}
@inject IJSRuntime JS

<li>
    <span @ref="elementRef" onclick="interopCall(this)">@message</span>
    <span style="display:@display">Not Updated Yet!</span>
</li>

@code {
    private DotNetObjectReference<ListItem2>? objRef;
    private ElementReference elementRef;
    private string display = "inline-block";
    private string message = "Select one of these list items.";

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            objRef = DotNetObjectReference.Create(this);
            await JS.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
        }
    }

    [JSInvokable]
    public void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        StateHasChanged();
    }

    public void Dispose() => objRef?.Dispose();
}
@inject IJSRuntime JS

<li>
    <span @ref="elementRef" onclick="interopCall(this)">@message</span>
    <span style="display:@display">Not Updated Yet!</span>
</li>

@code {
    private DotNetObjectReference<ListItem2>? objRef;
    private ElementReference elementRef;
    private string display = "inline-block";
    private string message = "Select one of these list items.";

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            objRef = DotNetObjectReference.Create(this);
            await JS.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
        }
    }

    [JSInvokable]
    public void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        StateHasChanged();
    }

    public void Dispose() => objRef?.Dispose();
}
@inject IJSRuntime JS

<li>
    <span @ref="elementRef" onclick="interopCall(this)">@message</span>
    <span style="display:@display">Not Updated Yet!</span>
</li>

@code {
    private DotNetObjectReference<ListItem2> objRef;
    private ElementReference elementRef;
    private string display = "inline-block";
    private string message = "Select one of these list items.";

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            objRef = DotNetObjectReference.Create(this);
            await JS.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
        }
    }

    [JSInvokable]
    public void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        StateHasChanged();
    }

    public void Dispose() => objRef?.Dispose();
}
@inject IJSRuntime JS

<li>
    <span @ref="elementRef" onclick="interopCall(this)">@message</span>
    <span style="display:@display">Not Updated Yet!</span>
</li>

@code {
    private DotNetObjectReference<ListItem2> objRef;
    private ElementReference elementRef;
    private string display = "inline-block";
    private string message = "Select one of these list items.";

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            objRef = DotNetObjectReference.Create(this);
            await JS.InvokeVoidAsync("assignDotNetHelper", elementRef, objRef);
        }
    }

    [JSInvokable]
    public void UpdateMessage()
    {
        message = "UpdateMessage Called!";
        display = "none";
        StateHasChanged();
    }

    public void Dispose() => objRef?.Dispose();
}

A következő szülőösszetevő négy listaelemet tartalmaz, amelyek mindegyike az ListItem2 összetevő egy-egy példánya.

CallDotnet7.razor:

@page "/call-dotnet-7"

<PageTitle>Call .NET 7</PageTitle>

<h1>Call .NET Example 7</h1>

<ul>
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
</ul>

CallDotnet7.razor:

@page "/call-dotnet-7"

<PageTitle>Call .NET 7</PageTitle>

<h1>Call .NET Example 7</h1>

<ul>
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
</ul>

CallDotNetExample7.razor:

@page "/call-dotnet-example-7"

<h1>Call .NET Example 7</h1>

<ul>
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
</ul>

CallDotNetExample7.razor:

@page "/call-dotnet-example-7"

<h1>Call .NET Example 7</h1>

<ul>
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
</ul>

CallDotNetExample7.razor:

@page "/call-dotnet-example-7"

<h1>Call .NET Example 7</h1>

<ul>
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
</ul>

CallDotNetExample7.razor:

@page "/call-dotnet-example-7"

<h1>Call .NET Example 7</h1>

<ul>
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
    <ListItem2 />
</ul>

Szinkron JS interoperabilitás az ügyféloldali elemekben

Ez a szakasz csak az ügyféloldali összetevőkre vonatkozik.

A JS interop hívások aszinkron módon történnek, függetlenül attól, hogy a hívott kód szinkron vagy aszinkron. A hívások aszinkron módon biztosítják, hogy az összetevők kompatibilisek legyenek a kiszolgálóoldali és az ügyféloldali renderelési módok között. A kiszolgálón minden JS interop-hívásnak aszinkronnak kell lennie, mert hálózati kapcsolaton keresztül küldi őket.

Ha biztosan tudja, hogy az összetevő csak a WebAssemblyen fut, választhat, hogy szinkron JS interop-hívásokat kezdeményez. Ez valamivel kisebb többletterheléssel jár, mint az aszinkron hívások végrehajtása, és kevesebb renderelési ciklust eredményezhet, mivel nincs köztes állapot az eredményekre várva.

Ha egy ügyféloldali összetevőben a JavaScriptből a .NET-be szeretne szinkron hívást kezdeményezni, használja DotNet.invokeMethod a DotNet.invokeMethodAsynchelyett.

A szinkron hívások akkor működnek, ha:

  • Az összetevő csak a WebAssemblyben való végrehajtáshoz lesz renderelve.
  • A hívott függvény szinkron módon ad vissza egy értéket. A függvény nem async metódus, és nem ad vissza .NET-Task vagy JavaScript-Promise.

JavaScript-hely

A JavaScript kód (JS) betöltése a JavaScript-elhelyezkedésről szóló cikkben ismertetett módszerek bármelyikével:

A JS modulok betöltéséről JS ebben a cikkben olvashat a JavaScript-elkülönítés JavaScript-modulokban című szakaszában .

Warning

Csak akkor helyezzen el <script> címkét egy összetevőfájlba (.razor), ha az összetevő garantáltan képes a statikus kiszolgálóoldali renderelésre (statikus SSR), mivel a <script> címke nem frissíthető dinamikusan.

Warning

Ne helyezzen <script> címkét egy összetevőfájlba (.razor), mert a <script> címke nem frissíthető dinamikusan.

JavaScript-elkülönítés JavaScript-modulokban

Blazor engedélyezi a JavaScript (JS) elkülönítését a standard JavaScript-modulokban (ECMAScript specifikáció). A JavaScript-modul betöltése ugyanúgy működik Blazor, mint más típusú webalkalmazások esetében, és szabadon testre szabhatja a modulok definiálását az alkalmazásban. A JavaScript-modulok használatáról további információt MDN Web Docs: JavaScript-modulokcímű témakörben talál.

JS elkülönítés a következő előnyöket biztosítja:

  • Az importált JS már nem szennyezi a globális névteret.
  • A könyvtárak és összetevők felhasználóinak nem szükséges importálniuk a kapcsolódó JS-t.

További információ: JavaScript-függvények meghívása a .NET-metódusokból ASP.NET Core Blazor.

A dinamikus importálást az import() operátorral az ASP.NET Core és a Blazortámogatja.

if ({CONDITION}) import("/additionalModule.js");

Az előző példában a {CONDITION} helyőrző egy feltételes ellenőrzést jelöl annak megállapításához, hogy be kell-e tölteni a modult.

A böngésző kompatibilitását lásd: Használhatom: JavaScript-modulok: dinamikus importálási.

Körkörös objektumhivatkozások elkerülése

A körkörös hivatkozásokat tartalmazó objektumok nem szerializálhatók az ügyfélen:

  • .NET-metódushívások.
  • JavaScript-metódushívások C#-ból, ha a visszatérési típus körkörös hivatkozásokat tartalmaz.

Bájttömb támogatása

Blazor támogatja az optimalizált bájttömb JavaScript (JS) interop használatát, amely megakadályozza a bájttömbök Base64-be való kódolását/dekódolását. Az alábbi példa az JS interopot használja arra, hogy egy bájttömböt adjon át a .NET-nek.

Adjon meg egy sendByteArrayJS függvényt. A függvényt statikusan hívjuk meg, amely tartalmazza a invokeMethodAsync hívás szerelvénynév paraméterét az összetevő egyik gombja alapján, és nem ad vissza értéket:

CallDotnet8.razor.js:

export function sendByteArray() {
  const data = new Uint8Array([0x45, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69,
    0x6e, 0x67, 0x27, 0x73, 0x20, 0x73, 0x68, 0x69, 0x6e, 0x79, 0x2c,
    0x20, 0x43, 0x61, 0x70, 0x74, 0x61, 0x69, 0x6e, 0x2e, 0x20, 0x4e,
    0x6f, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x72, 0x65, 0x74, 0x2e]);
  DotNet.invokeMethodAsync('BlazorSample', 'ReceiveByteArray', data)
    .then(str => {
      alert(str);
    });
}

export function addHandlers() {
  const btn = document.getElementById("btn");
  btn.addEventListener("click", sendByteArray);
}
<script>
  window.sendByteArray = () => {
    const data = new Uint8Array([0x45,0x76,0x65,0x72,0x79,0x74,0x68,0x69,
      0x6e,0x67,0x27,0x73,0x20,0x73,0x68,0x69,0x6e,0x79,0x2c,
      0x20,0x43,0x61,0x70,0x74,0x61,0x69,0x6e,0x2e,0x20,0x4e,
      0x6f,0x74,0x20,0x74,0x6f,0x20,0x66,0x72,0x65,0x74,0x2e]);
    DotNet.invokeMethodAsync('BlazorSample', 'ReceiveByteArray', data)
      .then(str => {
        alert(str);
      });
  };
</script>

Note

A JS helyére és az éles alkalmazásokkal kapcsolatos ajánlásainkra vonatkozó általános útmutatásért nézze meg a JavaScript-helyet az ASP.NET Core Blazor alkalmazásokban.

CallDotnet8.razor:

@page "/call-dotnet-8"
@using System.Text
@implements IAsyncDisposable
@inject IJSRuntime JS

<PageTitle>Call .NET 8</PageTitle>

<h1>Call .NET Example 8</h1>

<p>
    <button id="btn">Send Bytes</button>
</p>

<p>
    Quote ©2005 <a href="https://www.uphe.com">Universal Pictures</a>:
    <a href="https://www.uphe.com/movies/serenity-2005">Serenity</a><br>
    <a href="https://www.imdb.com/name/nm0821612/">Jewel Staite on IMDB</a>
</p>

@code {
    private IJSObjectReference? module;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            module = await JS.InvokeAsync<IJSObjectReference>("import", 
                "./Components/Pages/CallDotnet8.razor.js");

            await module.InvokeVoidAsync("addHandlers");
        }
    }

    [JSInvokable]
    public static Task<string> ReceiveByteArray(byte[] receivedBytes) => 
        Task.FromResult(Encoding.UTF8.GetString(receivedBytes, 0, 
            receivedBytes.Length));

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
        {
            try
            {
                await module.DisposeAsync();
            }
            catch (JSDisconnectedException)
            {
            }
        }
    }
}

CallDotnet8.razor:

@page "/call-dotnet-8"
@using System.Text
@implements IAsyncDisposable
@inject IJSRuntime JS

<PageTitle>Call .NET 8</PageTitle>

<h1>Call .NET Example 8</h1>

<p>
    <button id="btn">Send Bytes</button>
</p>

<p>
    Quote ©2005 <a href="https://www.uphe.com">Universal Pictures</a>:
    <a href="https://www.uphe.com/movies/serenity-2005">Serenity</a><br>
    <a href="https://www.imdb.com/name/nm0821612/">Jewel Staite on IMDB</a>
</p>

@code {
    private IJSObjectReference? module;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            module = await JS.InvokeAsync<IJSObjectReference>("import", 
                "./Components/Pages/CallDotnet8.razor.js");

            await module.InvokeVoidAsync("addHandlers");
        }
    }

    [JSInvokable]
    public static Task<string> ReceiveByteArray(byte[] receivedBytes) => 
        Task.FromResult(Encoding.UTF8.GetString(receivedBytes, 0, 
            receivedBytes.Length));

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
        {
            try
            {
                await module.DisposeAsync();
            }
            catch (JSDisconnectedException)
            {
            }
        }
    }
}

CallDotNetExample8.razor:

@page "/call-dotnet-example-8"
@using System.Text

<PageTitle>Call .NET 8</PageTitle>

<h1>Call .NET Example 8</h1>

<p>
    <button onclick="sendByteArray()">Send Bytes</button>
</p>

<p>
    Quote ©2005 <a href="https://www.uphe.com">Universal Pictures</a>:
    <a href="https://www.uphe.com/movies/serenity-2005">Serenity</a><br>
    <a href="https://www.imdb.com/name/nm0821612/">Jewel Staite on IMDB</a>
</p>

@code {
    [JSInvokable]
    public static Task<string> ReceiveByteArray(byte[] receivedBytes)
    {
        return Task.FromResult(
            Encoding.UTF8.GetString(receivedBytes, 0, receivedBytes.Length));
    }
}

CallDotNetExample8.razor:

@page "/call-dotnet-example-8"
@using System.Text

<h1>Call .NET Example 8</h1>

<p>
    <button onclick="sendByteArray()">Send Bytes</button>
</p>

<p>
    Quote ©2005 <a href="https://www.uphe.com">Universal Pictures</a>:
    <a href="https://www.uphe.com/movies/serenity-2005">Serenity</a><br>
    <a href="https://www.imdb.com/name/nm0821612/">Jewel Staite on IMDB</a>
</p>

@code {
    [JSInvokable]
    public static Task<string> ReceiveByteArray(byte[] receivedBytes)
    {
        return Task.FromResult(
            Encoding.UTF8.GetString(receivedBytes, 0, receivedBytes.Length));
    }
}

Ha a JavaScript .NET-ből való meghívása során bájttömböt használ, olvassa el a JavaScript-függvények .NET-metódusokból való meghívását a ASP.NET Core-ban Blazor.

Streamelés JavaScriptből .NET-be

Blazor közvetlenül JavaScriptből .NET-be streameli az adatokat. Az streameket a Microsoft.JSInterop.IJSStreamReference interfész használatával kérik.

Microsoft.JSInterop.IJSStreamReference.OpenReadStreamAsync visszaad egy értéket Stream , és a következő paramétereket használja:

  • maxAllowedSize: A JavaScript olvasási műveletéhez engedélyezett bájtok maximális száma, amely alapértelmezés szerint 512 000 bájt, ha nincs megadva.
  • cancellationToken: A CancellationToken az olvasás megszakításához.

JavaScriptben:

function streamToDotNet() {
  return new Uint8Array(10000000);
}

C#-kódban:

var dataReference = 
    await JS.InvokeAsync<IJSStreamReference>("streamToDotNet");
using var dataReferenceStream = 
    await dataReference.OpenReadStreamAsync(maxAllowedSize: 10_000_000);

var outputPath = Path.Combine(Path.GetTempPath(), "file.txt");
using var outputFileStream = File.OpenWrite(outputPath);
await dataReferenceStream.CopyToAsync(outputFileStream);

Az előző példában:

  • JS egy injektált IJSRuntime példány. A IJSRuntime-t a Blazor keretrendszer regisztrálja.
  • A dataReferenceStream az aktuális felhasználó ideiglenes mappaútvonalán lévő lemezre íródik (file.txt).

JavaScript-függvények meghívása .NET-metódusokból az ASP.NET Core-ban Blazor bemutatja a fordított műveletet: a .NET-ről a JavaScriptre való streamelést egy DotNetStreamReference.

ASP.NET Alapszintű Blazor fájlfeltöltések bemutatja, hogyan tölthet fel fájlokat a fájlba Blazor. A kiszolgálóoldali összetevőkben adatokat streamelő <textarea> űrlapok esetében lásd: ASP.NET Core-űrlapok Blazor hibaelhárítása.

JavaScript [JSImport]/[JSExport] interop

Ez a szakasz az ügyféloldali összetevőkre vonatkozik.

A JavaScript (JS) ügyféloldali összetevőkben való használatának alternatívájaként BlazorJSIJSRuntimeJS[JSImport]/[JSExport] interfészen alapuló interop api-ja érhető el a .NET 7 vagy újabb verziót célzó alkalmazások számára.

További információért lásd: JavaScript JSImport/JSExport interop ASP.NET Core-val Blazor.

JavaScript interop objektumhivatkozások megsemmisítése

A JavaScript (JS) interop cikkekben példák mutatnak be tipikus objektumelhelyezési mintákat:

JS interop objektumhivatkozások a hivatkozást létrehozó JS interop hívás oldalán található azonosító által kulcsolt térképként vannak implementálva. Ha az objektumelhelyezést a .NET vagy JS oldalról kezdeményezik, Blazor eltávolítja a bejegyzést a térképről, és az objektum szemétként gyűjthető, feltéve, hogy nincs más erős hivatkozás az objektumra.

Legalább a .NET oldalon létrehozott objektumokat mindig megsemmisítse, hogy elkerülje a .NET által felügyelt memória kiszivárgását.

DOM-tisztítási feladatok az összetevők ártalmatlanítása során

További információ: ASP.NET Core Blazor JavaScript-együttműködés (JS interop).

JavaScript interop hívások áramkör nélkül

További információ: ASP.NET Core Blazor JavaScript-együttműködés (JS interop).

További erőforrások