ASP.NET Core'daki JavaScript işlevlerinden .NET yöntemlerini çağırma Blazor

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Bu makalede JavaScript'ten (JS) .NET yöntemlerini çağırma açıklanmaktadır.

.NET'ten işlevleri çağırma hakkında bilgi için bkz. ASP.NET Core'daBlazor .NET yöntemlerinden JavaScript işlevlerini çağırmaJS.

Statik bir .NET yöntemi çağırma

JavaScript()JS uygulamasından statik bir .NET yöntemi çağırmak için şu işlevleri kullanın JS :

  • DotNet.invokeMethodAsync (önerilir): Hem sunucu tarafı hem de istemci tarafı bileşenleri için zaman uyumsuz.
  • DotNet.invokeMethod: Yalnızca istemci tarafı bileşenleri için zaman uyumlu.

yöntemini, statik .NET yönteminin tanımlayıcısını ve bağımsız değişkenleri içeren derlemenin adını geçirin.

Aşağıdaki örnekte:

  • Yer {ASSEMBLY NAME} tutucu, uygulamanın derleme adıdır.
  • Yer {.NET METHOD ID} tutucu , .NET yöntemi tanımlayıcısıdır.
  • Yer {ARGUMENTS} tutucu, yönteme geçirilecek isteğe bağlı, virgülle ayrılmış bağımsız değişkenlerdir ve bunların her biri ON-serializable olmalıdır JS.
DotNet.invokeMethodAsync('{ASSEMBLY NAME}', '{.NET METHOD ID}', {ARGUMENTS});

DotNet.invokeMethodAsync işlemin sonucunu temsil eden bir JS Promise döndürür. DotNet.invokeMethod (istemci tarafı bileşenleri) işlemin sonucunu döndürür.

Önemli

Sunucu tarafı bileşenleri için zaman uyumlu sürüm (invokeMethodAsync) üzerinden zaman uyumsuz işlevi (invokeMethod) öneririz.

.NET yöntemi genel, statik ve özniteliğine [JSInvokable]sahip olmalıdır.

Aşağıdaki örnekte:

  • Yer {<T>} tutucu, yalnızca değer döndüren yöntemler için gerekli olan dönüş türünü gösterir.
  • Yer {.NET METHOD ID} tutucu, yöntem tanımlayıcısıdır.
@code {
    [JSInvokable]
    public static Task{<T>} {.NET METHOD ID}()
    {
        ...
    }
}

Not

Açık genel yöntemlerin çağrılması statik .NET yöntemleriyle desteklenmez, ancak örnek yöntemleriyle desteklenir. Daha fazla bilgi için .NET genel sınıf yöntemlerini çağırma bölümüne bakın.

Aşağıdaki bileşende ReturnArrayAsync C# yöntemi bir int dizi döndürür. [JSInvokable] özniteliği yöntemine uygulanır ve yöntemi tarafından JSçağrılabilir hale getirir.

CallDotnet1.razor:

@page "/call-dotnet-1"

<PageTitle>Call .NET 1</PageTitle>

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

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

<p>
    See the result in the developer tools console.
</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 });
    }
}

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 });
    }
}

Öğesinin HTML özniteliği, JavaScript'in onclick olayları işlemek click için olay işleyicisi atamasıdır, 'nin @onclick yönerge özniteliği değildirBlazor.<button>onclick returnArrayAsyncJS İşlev işleyici olarak atanır.

Aşağıdaki returnArrayAsyncJS işlev, önceki bileşenin ReturnArrayAsync .NET yöntemini çağırır ve sonucu tarayıcının web geliştirici araçları konsoluna kaydeder. BlazorSample uygulamanın derleme adıdır.

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

Not

Konum hakkında genel yönergeler JS ve üretim uygulamalarına yönelik önerilerimiz için bkz . ASP.NET Core Blazor uygulamalarında JavaScript konumu.

Trigger .NET static method Düğme seçildiğinde, tarayıcının geliştirici araçları konsol çıkışı dizi verilerini görüntüler. Çıkışın biçimi tarayıcılar arasında biraz farklılık gösterir. Aşağıdaki çıkışta Microsoft Edge tarafından kullanılan biçim gösterilmektedir:

Array(3) [ 1, 2, 3 ]

Verileri bağımsız değişken olarak geçirerek işlevi çağırırken invokeMethodAsync bir .NET yöntemine veri geçirin.

.NET'e veri geçirmeyi göstermek için, önceki returnArrayAsyncJS işlevin işlev çağrıldığında bir başlangıç konumu almasını ve değeri işleve bağımsız değişken olarak geçirmesini invokeMethodAsync sağlayın:

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

Bileşende, işlev çağrısını başlangıç konumu içerecek şekilde değiştirin. Aşağıdaki örnekte değeri 5kullanılır:

<button onclick="returnArrayAsync(5)">
    ...
</button>

Bileşenin çağrılabilen ReturnArrayAsync yöntemi başlangıç konumunu alır ve diziyi ondan oluşturur. Dizi, konsolda günlüğe kaydetmek için döndürülür:

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

Uygulama yeniden derlenip tarayıcı yenilendikten sonra, düğme seçildiğinde tarayıcının konsolunda aşağıdaki çıkış görüntülenir:

Array(3) [ 5, 6, 7 ]

Varsayılan olarak, çağrısının JS .NET yöntem tanımlayıcısı .NET yöntemi adıdır, ancak öznitelik oluşturucuyu [JSInvokable] kullanarak farklı bir tanımlayıcı belirtebilirsiniz. Aşağıdaki örnekte, DifferentMethodName yöntemi için atanan yöntem tanımlayıcısı verilmiştir ReturnArrayAsync :

[JSInvokable("DifferentMethodName")]

çağrısında DotNet.invokeMethodAsync (sunucu tarafı veya istemci tarafı bileşenleri) veya DotNet.invokeMethod (yalnızca istemci tarafı bileşenleri) .NET yöntemini yürütmek için çağırın DifferentMethodNameReturnArrayAsync :

  • DotNet.invokeMethodAsync('BlazorSample', 'DifferentMethodName');
  • DotNet.invokeMethod('BlazorSample', 'DifferentMethodName'); (yalnızca istemci tarafı bileşenleri)

Not

ReturnArrayAsync Bu bölümdeki yöntem örneği, açık C# async ve await anahtar sözcükler kullanılmadan a Task sonucunu döndürür. ile asyncawait kodlama yöntemleri, zaman uyumsuz işlemlerin değerini döndürmek için anahtar sözcüğünü await kullanan yöntemlerin tipik bir örneğidir.

ReturnArrayAsyncve await anahtar sözcükleriyle async oluşturulan yöntem:

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

Daha fazla bilgi için C# kılavuzunda async ve await ile zaman uyumsuz programlama bölümüne bakın.

.NET'e geçirmek için JavaScript nesnesi ve veri başvuruları oluşturma

Nesne başvurusu oluşturmak için kullanılan .NET'e jsObjectJS Object geçirebilmek için nesne başvurusu oluşturmak JS için çağrısı DotNet.createJSObjectReference(jsObject) yapınJS. Aşağıdaki örnek, serileştirilebilir window olmayan nesneye başvuruyu .NET'e geçirir ve bunu C# yönteminde ReceiveWindowObject olarak IJSObjectReferencealır:

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

Yukarıdaki örnekte yer tutucu, {ASSEMBLY NAME} uygulamanın ad alanıdır.

Not

Yukarıdaki örnek, nesnesine JSObjectReferenceyönelik bir başvuru içinde JStutulmadığından, öğesinin window atılması gerekmez.

bir başvurunun JSObjectReference korunması, istemcide bellek sızıntısını JS önlemek için bu başvurunun atılmasını gerektirir. Aşağıdaki örnek, önceki kodu yeniden düzenleyerek öğesine bir başvuru yakalar ve ardından başvuruyu JSObjectReferenceatmak için DotNet.disposeJSObjectReference() bir çağrı yapar:

var jsObjectReference = DotNet.createJSObjectReference(window);

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

DotNet.disposeJSObjectReference(jsObjectReference);

Yukarıdaki örnekte yer tutucu, {ASSEMBLY NAME} uygulamanın ad alanıdır.

Akış başvurusu oluşturmak için kullanılan . NET'e BlobUint8ArraystreamReferenceFloat32ArrayArrayBuffergeçirilebilmesi için bir akış başvurusu oluşturmak JSJS için çağrısı DotNet.createJSStreamReference(streamReference) yapın.

Örnek .NET yöntemini çağırma

JavaScript'ten bir örnek .NET yöntemi çağırmak için (JS):

  • .NET örneğini bir içinde sarmalayarak DotNetObjectReference ve üzerinde çağırarak Create başvuruya JS göre geçirin.

  • geçirilen DotNetObjectReferenceiçinden bir .NET örneği yöntemini JS (önerilen) veya invokeMethod (yalnızca istemci tarafı bileşenleri) kullanarak invokeMethodAsync çağırın. Örnek .NET yönteminin tanımlayıcısını ve bağımsız değişkenleri geçirin. .NET örneği, 'den JSdiğer .NET yöntemleri çağrılırken bağımsız değişken olarak da geçirilebilir.

    Aşağıdaki örnekte:

    • dotNetHelper bir DotNetObjectReference' dir.
    • Yer {.NET METHOD ID} tutucu , .NET yöntemi tanımlayıcısıdır.
    • Yer {ARGUMENTS} tutucu, yönteme geçirilecek isteğe bağlı, virgülle ayrılmış bağımsız değişkenlerdir ve bunların her biri ON-serializable olmalıdır JS.
    dotNetHelper.invokeMethodAsync('{.NET METHOD ID}', {ARGUMENTS});
    

    Not

    invokeMethodAsync ve invokeMethod bir örnek yöntemini çağırırken derleme adı parametresini kabul etmeyin.

    invokeMethodAsync işlemin sonucunu temsil eden bir JS Promise döndürür. invokeMethod (yalnızca istemci tarafı bileşenleri) işlemin sonucunu döndürür.

    Önemli

    Sunucu tarafı bileşenleri için zaman uyumlu sürüm (invokeMethodAsync) üzerinden zaman uyumsuz işlevi (invokeMethod) öneririz.

  • DotNetObjectReferenceatın.

Bu makalenin aşağıdaki bölümlerinde bir örnek .NET yöntemini çağırmaya yönelik çeşitli yaklaşımlar gösterilmektedir:

JavaScript tarafından çağrılabilen .NET yöntemlerini kırpmaktan kaçının

Bu bölüm, önceden derleme (AOT) derlemesi ve çalışma zamanı yeniden bağlantısının etkinleştirildiği istemci tarafı uygulamaları için geçerlidir.

Aşağıdaki bölümlerdeki örneklerin bazıları, özniteliğiyle [JSInvokable] işaretlenmiş JavaScript tarafından çağrılabilen .NET yönteminin bileşen olmayan Razor bir sınıfın üyesi olduğu sınıf örneği yaklaşımını temel alır. Bu tür .NET yöntemleri bir Razor bileşende bulunduğunda, çalışma zamanını yeniden bağlama/kırpmaya karşı korunurlar. .NET yöntemlerini bileşenlerin dışında Razor kırpmaya karşı korumak için, aşağıdaki örnekte gösterildiği gibi, sınıfın oluşturucusunda özniteliğiyle DynamicDependency yöntemleri uygulayın:

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

public class ExampleClass {

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

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

Daha fazla bilgi için bkz . .NET kitaplıklarını kırpma için hazırlama: DynamicDependency.

Tek bir JavaScript işlevine a DotNetObjectReference geçirme

Bu bölümdeki örnekte, tek bir DotNetObjectReference JavaScript (JS) işlevine nasıl geçiş yapılacağını gösterilmektedir.

Aşağıdaki sayHello1JS işlev bir DotNetObjectReference bileşenin GetHelloMessage .NET yöntemini çağırmak için bir alır ve çağırırinvokeMethodAsync:

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

Not

Konum hakkında genel yönergeler JS ve üretim uygulamalarına yönelik önerilerimiz için bkz . ASP.NET Core Blazor uygulamalarında JavaScript konumu.

Yukarıdaki örnekte değişken adı dotNetHelper rastgeledir ve tercih edilen herhangi bir adla değiştirilebilir.

Aşağıdaki bileşen için:

  • Bileşenin adlı GetHelloMessage-JSinvokable .NET yöntemi vardır.
  • Trigger .NET instance method Düğme seçildiğinde, JS işlevi sayHello1 ile çağrılırDotNetObjectReference.
  • sayHello1:
    • İleti sonucunu çağırır GetHelloMessage ve alır.
    • çağrı TriggerDotNetInstanceMethod yöntemine ileti sonucunu döndürür.
  • 'den sayHello1result döndürülen ileti kullanıcıya görüntülenir.
  • Bellek sızıntısını önlemek ve çöp toplamaya izin vermek için tarafından oluşturulan DotNetObjectReference .NET nesne başvurusu yönteminde Dispose atılır.

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();
    }
}

Yukarıdaki örnekte değişken adı dotNetHelper rastgeledir ve tercih edilen herhangi bir adla değiştirilebilir.

Bağımsız değişkenleri bir örnek yöntemine geçirmek için aşağıdaki kılavuzu kullanın:

.NET yöntemi çağırmasına parametreler ekleyin. Aşağıdaki örnekte yöntemine bir ad geçirilir. Gerektiğinde listeye ek parametreler ekleyin.

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

Yukarıdaki örnekte değişken adı dotNetHelper rastgeledir ve tercih edilen herhangi bir adla değiştirilebilir.

.NET yöntemine parametre listesini sağlayın.

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();
    }
}

Yukarıdaki örnekte değişken adı dotNetHelper rastgeledir ve tercih edilen herhangi bir adla değiştirilebilir.

DotNetObjectReference Birden çok JavaScript işlevine sahip bir sınıfa geçirme

Bu bölümdeki örnekte, birden çok işleve sahip bir DotNetObjectReference JavaScript (JS) sınıfına nasıl geçiş yapılacağını gösterilmektedir.

Birden çok işlevin kullanması için yaşam döngüsü yönteminden bir JS sınıfı oluşturun ve geçirinDotNetObjectReference.OnAfterRenderAsync Aşağıdaki örnekte gösterildiği gibi .NET kodunun DotNetObjectReferenceatıldığından emin olun.

Aşağıdaki bileşende Trigger JS function düğmeler, yönerge özniteliğini değilBlazor@onclick özelliğini ayarlayarakonclickJSişlevleri çağırır.JS

CallDotNetExampleOneHelper.razor:

@page "/call-dotnet-example-one-helper"
@implements IDisposable
@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 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();
    }
}
@page "/call-dotnet-example-one-helper"
@implements IDisposable
@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 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();
    }
}
@page "/call-dotnet-example-one-helper"
@implements IDisposable
@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 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()
    {
        if (dotNetHelper is not null)
        {
            dotNetHelper.Dispose();
        }
    }
}

Yukarıdaki örnekte:

  • JS eklenen IJSRuntime bir örnektir. IJSRuntime , çerçeve tarafından Blazor kaydedilir.
  • Değişken adı dotNetHelper rastgeledir ve tercih edilen herhangi bir adla değiştirilebilir.
  • Bileşenin, atık toplamaya izin vermek ve bellek sızıntısını DotNetObjectReference önlemek için öğesini açıkça atması gerekir.
<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>

Not

Konum hakkında genel yönergeler JS ve üretim uygulamalarına yönelik önerilerimiz için bkz . ASP.NET Core Blazor uygulamalarında JavaScript konumu.

Yukarıdaki örnekte:

  • GreetingHelpers sınıfı genel olarak tanımlamak için nesnesine window eklenir ve bu da birlikte çalışma için JS sınıfın bulunmasına izin verirBlazor.
  • Değişken adı dotNetHelper rastgeledir ve tercih edilen herhangi bir adla değiştirilebilir.

.NET genel sınıf yöntemlerini çağırma

JavaScript (JS) işlevleri, bir JS işlevin genel bir sınıfın .NET yöntemini çağırdığı .NET genel sınıf yöntemlerini çağırabilir.

Aşağıdaki genel tür sınıfında (GenericType<TValue>):

  • sınıfı, tek bir genel Value özelliğe sahip tek tür parametresine (TValue) sahiptir.
  • sınıfında özniteliğiyle [JSInvokable]işaretlenmiş iki genel olmayan yöntem vardır ve her biri adlı newValuegenel tür parametresine sahiptir:
    • Update öğesinin değerini ValuenewValuezaman uyumlu olarak güncelleştirir.
    • UpdateAsynczaman uyumsuz olarak beklenen bir görev Task.Yield oluşturduktan sonra değerinin değerini ValuenewValue, beklenen zaman uyumsuz olarak geçerli bağlama geri döndürecek şekilde güncelleştirir.
  • Sınıf yöntemlerinin her biri türünü ve değerini Value konsoluna yazarTValue. Konsola yazmak yalnızca gösterim amaçlıdır. Üretim uygulamaları genellikle uygulama günlüğü yerine konsola yazmaktan kaçınır. Daha fazla bilgi için bkz. ASP.NET Core Blazor günlüğü ve .NET Core ve ASP.NET Core'da günlüğe kaydetme.

Not

Açık genel türler ve yöntemler , tür yer tutucuları için türleri belirtmez. Buna karşılık, kapalı genel türler tüm tür yer tutucuları için tür sağlar. Bu bölümdeki örneklerde kapalı genel değerler gösterilmektedir, ancak açık genel ayarlarla birlikte çalışma örneği yöntemlerini çağırmak JS desteklenir. Bu makalenin önceki bölümlerinde açıklanan statik .NET yöntemi çağrıları için açık genel türlerin kullanımı desteklenmez.

Daha fazla bilgi için aşağıdaki makaleleri inceleyin:

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 void UpdateAsync(TValue newValue)
    {
        await Task.Yield();
        Value = newValue;

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

Aşağıdaki invokeMethodsAsync işlevde:

  • Genel tür sınıfının Update ve UpdateAsync yöntemleri, dizeleri ve sayıları temsil eden bağımsız değişkenlerle çağrılır.
  • İstemci tarafı bileşenleri ile invokeMethodzaman uyumlu olarak .NET yöntemlerini çağırmayı destekler. syncInterop , birlikte çalışmanın JS istemcide oluşup oluşmadığını belirten bir boole değeri alır. olduğunda syncInteroptrueinvokeMethod güvenli bir şekilde çağrılır. değeri syncInterop isefalse, birlikte çalışma sunucu tarafı bileşeninde yürütülmekte olduğundan JS yalnızca zaman uyumsuz işlev invokeMethodAsync çağrılır.
  • Gösterim amacıyla, DotNetObjectReference işlev çağrısı (invokeMethod veya invokeMethodAsync), adlı .NET yöntemi (Update veya UpdateAsync) ve bağımsız değişkeni konsola yazılır. Bağımsız değişkenler, işlev çağrısının JS .NET yöntemi çağrısıyla (.NET tarafındaki konsola da yazılır) eşleşmesine izin vermek için rastgele bir sayı kullanır. Üretim kodu genellikle istemcide veya sunucuda konsola yazmaz. Üretim uygulamaları genellikle uygulama günlüğüne kaydetmeyi kullanır. Daha fazla bilgi için bkz. ASP.NET Core Blazor günlüğü ve .NET Core ve ASP.NET Core'da günlüğe kaydetme.
<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>

Not

Konum hakkında genel yönergeler JS ve üretim uygulamalarına yönelik önerilerimiz için bkz . ASP.NET Core Blazor uygulamalarında JavaScript konumu.

Aşağıdaki GenericsExample bileşeninde:

  • Düğme JS seçildiğinde işlev invokeMethodsAsync çağrılır Invoke Interop .
  • bir tür çifti DotNetObjectReference oluşturulur ve örnekleri için işlevine GenericTypestringintgeçirilir.JS

GenericsExample.razor:

@page "/generics-example"
@using System.Runtime.InteropServices
@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 =
            RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"));

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

    public void Dispose()
    {
        objRef1?.Dispose();
        objRef2?.Dispose();
    }
}
@page "/generics-example"
@using System.Runtime.InteropServices
@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 =
            RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER"));

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

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

Yukarıdaki örnekte, JS eklenen IJSRuntime bir örnektir. IJSRuntime , çerçeve tarafından Blazor kaydedilir.

Aşağıda, bir istemci tarafı bileşeninde düğme seçildiğinde önceki örneğin Invoke Interop tipik çıkışı gösterilmektedir:

JS: invokeMethodAsync:Update('string 37802')
.NET: Güncelleştirme: GenericType<System.String>: string 37802
JS: invokeMethodAsync:UpdateAsync('string 53051')
JS: invokeMethod:Update('string 26784')
.NET: Güncelleştirme: GenericType<System.String>: dize 26784
JS: invokeMethodAsync:Update(14107)
.NET: Güncelleştirme: GenericType<System.Int32>: 14107
JS: invokeMethodAsync:UpdateAsync(48995)
JS: invokeMethod:Update(12872)
.NET: Güncelleştirme: GenericType<System.Int32>: 12872
.NET: UpdateAsync: GenericType<System.String>: string 53051
.NET: UpdateAsync: GenericType<System.Int32>: 48995

Yukarıdaki örnek bir sunucu tarafı bileşeninde uygulanıyorsa ile zaman uyumlu çağrılardan invokeMethod kaçınılır. Sunucu tarafı bileşenleri için zaman uyumlu sürüm (invokeMethodAsync) üzerinden zaman uyumsuz işlevi (invokeMethod) öneririz.

Sunucu tarafı bileşeninin tipik çıkışı:

JS: invokeMethodAsync:Update('string 34809')
.NET: Güncelleştirme: GenericType<System.String>: dize 34809
JS: invokeMethodAsync:UpdateAsync('string 93059')
JS: invokeMethodAsync:Update(41997)
.NET: Güncelleştirme: GenericType<System.Int32>: 41997
JS: invokeMethodAsync:UpdateAsync(24652)
.NET: UpdateAsync: GenericType<System.String>: string 93059
.NET: UpdateAsync: GenericType<System.Int32>: 24652

Yukarıdaki çıkış örnekleri, zaman uyumsuz yöntemlerin iş parçacığı zamanlama ve yöntem yürütme hızı gibi çeşitli faktörlere bağlı olarak rastgele bir sırada yürütüldüğünü ve tamamlandığını gösterir. Zaman uyumsuz yöntem çağrıları için tamamlanma sırasını güvenilir bir şekilde tahmin etmek mümkün değildir.

Sınıf örneği örnekleri

Aşağıdaki sayHello1JS işlev:

  • GetHelloMessage geçirilen DotNetObjectReferenceüzerinde .NET yöntemini çağırır.
  • iletiyi GetHelloMessage çağırana sayHello1 döndürür.
<script>
  window.sayHello1 = (dotNetHelper) => {
    return dotNetHelper.invokeMethodAsync('GetHelloMessage');
  };
</script>

Not

Konum hakkında genel yönergeler JS ve üretim uygulamalarına yönelik önerilerimiz için bkz . ASP.NET Core Blazor uygulamalarında JavaScript konumu.

Yukarıdaki örnekte değişken adı dotNetHelper rastgeledir ve tercih edilen herhangi bir adla değiştirilebilir.

Aşağıdaki HelloHelper sınıfta adlı GetHelloMessage-JSinvokable .NET yöntemi vardır. Oluşturulduğunda HelloHelper , özelliğindeki Name ad' dan GetHelloMessagebir ileti döndürmek için kullanılır.

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;

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}!";
}

CallHelloHelperGetHelloMessage Aşağıdaki JsInteropClasses3 sınıftaki yöntemi, işlevini sayHello1 yeni bir örneğiyle HelloHelperçağırırJS.

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;

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);
    }
}

Bellek sızıntısını önlemek ve çöp toplamaya izin vermek için, nesne başvurusu söz dizimi ile using var kapsamın dışına çıktığında tarafından DotNetObjectReference oluşturulan .NET nesne başvurusu atılır.

Trigger .NET instance method Aşağıdaki bileşende düğme seçildiğinde değeriyle JsInteropClasses3.CallHelloHelperGetHelloMessage çağrılırname.

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);
    }
}

Aşağıdaki görüntüde, alanda adıyla Amy Pond işlenen bileşen gösterilmektedir Name . Düğme seçildikten sonra kullanıcı Hello, Amy Pond! arabiriminde görüntülenir:

İşlenen 'CallDotNetExample4' bileşen örneği

Sınıfında gösterilen JsInteropClasses3 önceki desen de tamamen bir bileşende uygulanabilir.

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);
    }
}

Bellek sızıntısını önlemek ve çöp toplamaya izin vermek için, nesne başvurusu söz dizimi ile using var kapsamın dışına çıktığında tarafından DotNetObjectReference oluşturulan .NET nesne başvurusu atılır.

Bileşen tarafından görüntülenen çıkış, Hello, Amy Pond! alanda adın Amy Pondname sağlandığı zamandır.

Önceki bileşende .NET nesne başvurusu atılır. Bir sınıf veya bileşen atmazsaDotNetObjectReference, geçirilen DotNetObjectReferenceöğesini çağırarak dispose istemciden atın:

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

Yukarıdaki örnekte:

  • Yer {JS FUNCTION NAME} tutucu işlevin JS adıdır.
  • Değişken adı dotNetHelper rastgeledir ve tercih edilen herhangi bir adla değiştirilebilir.
  • Yer {.NET METHOD ID} tutucu , .NET yöntemi tanımlayıcısıdır.

Bileşen örneği .NET yöntemi yardımcı sınıfı

Yardımcı sınıf bir .NET örnek yöntemini olarak Actionçağırabilir. Yardımcı sınıflar aşağıdaki senaryolarda kullanışlıdır:

  • Aynı türde birkaç bileşen aynı sayfada işlendiğinde.
  • Aynı bileşeni aynı anda kullanan birden çok kullanıcı içeren sunucu tarafı uygulamalarda.

Aşağıdaki örnekte:

  • Bileşen, uygulamanın Shared klasöründe paylaşılan bir bileşen olan çeşitli ListItem1 bileşenler içerir.
  • Her ListItem1 bileşen bir ileti ve bir düğmeden oluşur.
  • Bir ListItem1 bileşen düğmesi seçildiğinde, bu ListItem1UpdateMessage yöntem liste öğesi metnini değiştirir ve düğmeyi gizler.

Aşağıdaki MessageUpdateInvokeHelper sınıf, UpdateMessageCallersınıf örneği oluşturulurken belirtilen öğesini çağırmak Action için -invokable .NET yöntemini tutarJS.

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;

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();
    }
}

Aşağıdaki updateMessageCallerJS işlev .NET yöntemini çağırır UpdateMessageCaller .

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

Not

Konum hakkında genel yönergeler JS ve üretim uygulamalarına yönelik önerilerimiz için bkz . ASP.NET Core Blazor uygulamalarında JavaScript konumu.

Yukarıdaki örnekte değişken adı dotNetHelper rastgeledir ve tercih edilen herhangi bir adla değiştirilebilir.

Aşağıdaki ListItem1 bileşen, bir üst bileşende birkaç kez kullanılabilen ve bir HTML listesi ( veya <ol>...</ol>) için liste öğeleri (<li>...</li><ul>...</ul>) oluşturan paylaşılan bir bileşendir. Her ListItem1 bileşen örneği, yöntemine UpdateMessage ayarlanmış bir Action örneği MessageUpdateInvokeHelper oluşturur.

Bir ListItem1 bileşenin InteropCall düğmesi seçildiğinde, updateMessageCaller örnek için oluşturulan DotNetObjectReference ile çağrılır MessageUpdateInvokeHelper . Bu, çerçevenin söz konusu ListItem1MessageUpdateInvokeHelper örneğini çağırmasına UpdateMessageCaller izin verir. Geçirilen DotNetObjectReference () içinde JSdotNetHelper.dispose()atılır.

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()
    {
        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 içinde ayarlandığında kullanıcı arabirimini message güncelleştirmek için çağrılır UpdateMessage. Çağrılmazsa StateHasChanged , Blazor kullanıcı arabirimi çağrıldığında güncelleştirilmesi gerektiğini bilmenin Action bir yolu yoktur.

Aşağıdaki üst bileşen, her biri bileşenin bir örneği olmak ListItem1 üzere dört liste öğesi içerir.

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>

Aşağıdaki görüntüde, ikinci InteropCall düğme seçildikten sonra işlenen üst bileşen gösterilmektedir:

  • İkinci ListItem1 bileşen iletiyi görüntüledi UpdateMessage Called! .
  • düğmenin InteropCall CSS display özelliği olarak ayarlandığındannone, ikinci ListItem1 bileşenin düğmesi görünmez.

İşlenen 'CallDotNetExample6' bileşen örneği

Bir öğe özelliğine atanan öğesinden DotNetObjectReference çağrılan bileşen örneği .NET yöntemi

bir DotNetObjectReference HTML öğesinin özelliğine atanma, bileşen örneğinde .NET yöntemlerinin çağrılmalarına izin verir:

Bileşen örneği .NET yöntemi yardımcı sınıfı bölümünde açıklanan yaklaşıma benzer şekilde, bu yaklaşım aşağıdaki senaryolarda kullanışlıdır:

  • Aynı türde birkaç bileşen aynı sayfada işlendiğinde.
  • Aynı bileşeni aynı anda kullanan birden çok kullanıcı içeren sunucu tarafı uygulamalarda.
  • .NET yöntemi bir JS olaydan (örneğin, onclick) çağrılır( örneğin, ) bir Blazor olaydan değil. @onclick

Aşağıdaki örnekte:

  • Bileşen, uygulamanın Shared klasöründe paylaşılan bir bileşen olan çeşitli ListItem2 bileşenler içerir.
  • Her ListItem2 bileşen bir liste öğesi iletisinden ve css <span> özelliği görüntü için olarak ayarlanmış inline-block ikinci bir display iletiden <span> oluşur.
  • Bir ListItem2 bileşen liste öğesi seçildiğinde, bu ListItem2UpdateMessage yöntem birincideki <span> liste öğesi metnini değiştirir ve özelliğini noneolarak ayarlayarak ikincisini <span> gizlerdisplay.

Aşağıdaki assignDotNetHelperJS işlev, adlı dotNetHelperbir özellikteki öğesine öğesini atarDotNetObjectReference:

<script>
  window.assignDotNetHelper = (element, dotNetHelper) => {
    element.dotNetHelper = dotNetHelper;
  }
</script>

Aşağıdaki interopCallJS işlev, adlı UpdateMessagebir .NET yöntemini çağırmak için geçirilen öğesini kullanırDotNetObjectReference:

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

Not

Konum hakkında genel yönergeler JS ve üretim uygulamalarına yönelik önerilerimiz için bkz . ASP.NET Core Blazor uygulamalarında JavaScript konumu.

Yukarıdaki örnekte değişken adı dotNetHelper rastgeledir ve tercih edilen herhangi bir adla değiştirilebilir.

Aşağıdaki ListItem2 bileşen, bir üst bileşende birkaç kez kullanılabilen ve bir HTML listesi ( veya <ol>...</ol>) için liste öğeleri (<li>...</li><ul>...</ul>) oluşturan paylaşılan bir bileşendir.

Her ListItem2 bileşen örneği içindeki işlevini OnAfterRenderAsync bir öğe başvurusuyla (liste öğesinin ilk <span> öğesi) ve bileşen örneğini olarak DotNetObjectReferenceçağırırassignDotNetHelperJS.

Bir ListItem2 bileşenin iletisi <span> seçildiğinde, interopCall öğesini parametre ()this olarak geçirerek <span> çağrılır ve bu da .NET yöntemini çağırır UpdateMessage . StateHasChanged içindeUpdateMessage, ayarlandığında kullanıcı arabirimini message güncelleştirmek için çağrılır ve display ikincinin <span> özelliği güncelleştirilir. Çağrılmazsa StateHasChanged , Blazor yöntem çağrıldığında kullanıcı arabiriminin güncelleştirilmesi gerektiğini bilmenin hiçbir yolu yoktur.

DotNetObjectReference, bileşen atıldığında atılır.

ListItem2.razor:

@inject IJSRuntime JS

<li>
    <span style="font-weight:bold;color:@color" @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.";
    private string color = "initial";

    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";
        color = "MediumSeaGreen";
        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();
}
@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şağıdaki üst bileşen, her biri bileşenin bir örneği olmak ListItem2 üzere dört liste öğesi içerir.

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>

İstemci tarafı bileşenlerinde zaman uyumlu JS birlikte çalışma

Bu bölüm yalnızca istemci tarafı bileşenleri için geçerlidir.

JS interop çağrıları, çağrılan kodun zaman uyumlu veya zaman uyumsuz olmasına bakılmaksızın varsayılan olarak zaman uyumsuzdur. Bileşenlerin sunucu tarafı ve istemci tarafı işleme modları arasında uyumlu olduğundan emin olmak için çağrılar varsayılan olarak zaman uyumsuz olarak yapılır. Sunucuda, tüm JS birlikte çalışma çağrıları bir ağ bağlantısı üzerinden gönderildiğinden zaman uyumsuz olmalıdır.

Bileşeninizin yalnızca WebAssembly üzerinde çalıştığından JS eminseniz zaman uyumlu birlikte çalışma çağrıları yapmayı seçebilirsiniz. Bu, zaman uyumsuz çağrılar yapmaktan biraz daha az ek yüke sahiptir ve sonuçları beklerken ara durum olmadığından daha az işleme döngüsüne neden olabilir.

İstemci tarafı bileşeninde JavaScript'ten .NET'e zaman uyumlu bir çağrı yapmak için yerine DotNet.invokeMethodAsynckullanınDotNet.invokeMethod.

Zaman uyumlu çağrılar şu durumlarda çalışır:

  • Bileşen yalnızca WebAssembly'de yürütülmeye yönelik olarak işlenir.
  • Çağrılan işlev zaman uyumlu olarak bir değer döndürür. İşlev bir async yöntem değildir ve .NET Task veya JavaScript Promisedöndürmez.

JavaScript konumu

JavaScript konumu makalesinde açıklanan yaklaşımlardan herhangi birini kullanarak JavaScript (JS) kodunu yükleyin:

JS Yüklemek JS için modülleri kullanma, bu makalede JavaScript modüllerinde JavaScript yalıtımı bölümünde açıklanmıştır.

Uyarı

Etiket dinamik olarak güncelleştirilemediğinden, yalnızca bileşenin statik sunucu tarafı işlemeyi (statik SSR) benimsemesi garanti edilirse bir bileşen dosyasına (.razor) etiket yerleştirin<script>.<script>

Uyarı

Etiket dinamik olarak güncelleştirilemediğinden <script> bir etiketi bileşen dosyasına (.razor) yerleştirmeyin<script>.

JavaScript modüllerinde JavaScript yalıtımı

Blazor, standart JavaScript modüllerinde JavaScript (JS) yalıtımını etkinleştirir (ECMAScript belirtimi). JavaScript modülü yükleme işlemi, diğer web uygulaması türleriyle aynı şekilde Blazor çalışır ve modüllerin uygulamanızda nasıl tanımlandığını özelleştirebilirsiniz. JavaScript modüllerini kullanma kılavuzu için bkz . MDN Web Belgeleri: JavaScript modülleri.

JS yalıtımı aşağıdaki avantajları sağlar:

  • İçeri aktarılan JS artık genel ad alanını kirletmez.
  • Kitaplık ve bileşenlerin kullanıcılarının ilgili JS'yi içeri aktarması gerekmez.

Daha fazla bilgi için bkz. ASP.NET Core Blazor'da .NET yöntemlerinden JavaScript işlevlerini çağırma.

işleciyle import() dinamik içeri aktarma, ASP.NET Core ve Blazorile desteklenir:

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

Yukarıdaki örnekte yer tutucu, modülün {CONDITION} yüklenmesi gerekip gerekmediğini belirlemek için koşullu denetimi temsil eder.

Tarayıcı uyumluluğu için bkz . Kullanabilir miyim: JavaScript modülleri: dinamik içeri aktarma.

Döngüsel nesne başvurularından kaçının

Döngüsel başvurular içeren nesneler istemcide aşağıdakilerden biri için seri hale getirilemez:

  • .NET yöntemi çağrıları.
  • Dönüş türü döngüsel başvurulara sahip olduğunda JavaScript yöntemi C# dilinden çağrılar.

Bayt dizisi desteği

Blazor , bayt dizilerinin Base64'e kodlanması/kodunun çözülmesini önleyen iyileştirilmiş bayt dizisi JavaScript (JS) birlikte çalışmasını destekler. Aşağıdaki örnek, .NET'e bayt dizisi geçirmek için birlikte çalışma kullanır JS .

Bir sendByteArrayJS işlev sağlayın. İşlev, bileşendeki bir düğme tarafından çağrıda invokeMethodAsync derleme adı parametresini içeren statik olarak çağrılır ve bir değer döndürmez:

<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>

Not

Konum hakkında genel yönergeler JS ve üretim uygulamalarına yönelik önerilerimiz için bkz . ASP.NET Core Blazor uygulamalarında JavaScript konumu.

CallDotnet8.razor:

@page "/call-dotnet-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

<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

<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));
    }
}

.NET'ten JavaScript çağırırken bayt dizisi kullanma hakkında bilgi için bkz . ASP.NET Core'da Blazor.NET yöntemlerinden JavaScript işlevlerini çağırma.

JavaScript'ten .NET'e akış

Blazor doğrudan JavaScript'ten .NET'e veri akışını destekler. arabirimi kullanılarak Microsoft.JSInterop.IJSStreamReference Akışlar istenir.

Microsoft.JSInterop.IJSStreamReference.OpenReadStreamAsync ve Stream döndürür ve aşağıdaki parametreleri kullanır:

  • maxAllowedSize: JavaScript'ten okuma işlemi için izin verilen bayt sayısı üst sınırı; belirtilmezse varsayılan olarak 512.000 bayt olur.
  • cancellationToken: Okuma işlemini iptal etme için A CancellationToken .

JavaScript'te:

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

C# kodunda:

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);

Yukarıdaki örnekte:

  • JS eklenen IJSRuntime bir örnektir. IJSRuntime , çerçeve tarafından Blazor kaydedilir.
  • dataReferenceStream, geçerli kullanıcının geçici klasör yolunda (file.txt) diske (GetTempPath) yazılır.

ASP.NET Core'daki Blazor .NET yöntemlerinden JavaScript işlevlerini çağırmak ters işlemi kapsar ve kullanarak DotNetStreamReference.NET'ten JavaScript'e akış sağlar.

ASP.NET Core Blazor dosya yüklemeleri , içinde Blazorbir dosyanın nasıl karşıya yüklendiğini kapsar. Sunucu tarafı bileşeninde veri akışı <textarea> sağlayan bir form örneği için bkz . ASP.NET Çekirdek Blazor formlarında sorun giderme.

JavaScript [JSImport]/[JSExport] birlikte çalışma

Bu bölüm istemci tarafı bileşenleri için geçerlidir.

'nin arabirime dayalı birlikte çalışma mekanizmasını kullanarak Blazoristemci tarafı bileşenlerinde JavaScript (JS) ile etkileşime alternatif olarak, .NET 7 veya sonraki sürümleri hedefleyen uygulamalar için birlikte[JSImport]JS/[JSExport] çalışma API'sini kullanabilirsiniz.IJSRuntimeJS

Daha fazla bilgi için bkz. ASP.NET Core Blazorile JavaScript JSİçeri/JSDışarı Aktarma birlikte çalışma .

JavaScript birlikte çalışma nesnesi başvurularının elden çıkarılması

JavaScript (JS) birlikte çalışma makalelerinin tüm örnekleri tipik nesne atma desenlerini gösterir:

  • Bu makalede açıklandığı gibi 'den JS.NET'i çağırırken, .NET belleğinin sızmasını önlemek için .NET'ten veya kaynağından JS oluşturulan DotNetObjectReference bir öğesini atın.

  • .NET'ten çağırırkenJS, ASP.NET Core'daki Blazor.NET yöntemlerinden JavaScript işlevlerini çağırma bölümünde açıklandığı gibi, bellek sızıntısını JS önlemek için .NET'ten veya kaynağından JS oluşturulanlarıJSObjectReferenceIJSObjectReference/IJSInProcessObjectReference/atın.

JS birlikte çalışma nesne başvuruları, birlikte çalışma çağrısının JS yanında başvuruyu oluşturan bir tanımlayıcı tarafından anahtarlanan bir eşleme olarak uygulanır. Nesne atma işlemi .NET'ten veya JS taraftan başlatıldığında, Blazor girdiyi eşlemeden kaldırır ve nesneye başka güçlü bir başvuru olmadığı sürece nesne çöp olarak toplanabilir.

.NET yönetilen belleğinin sızmasını önlemek için en azından .NET tarafında oluşturulan nesneleri her zaman atın.

Bileşen atma sırasında DOM temizleme görevleri

Daha fazla bilgi için bkz. ASP.NET Core Blazor JavaScript birlikte çalışabilirliği (JSbirlikte çalışma).

Bağlantı hattı olmayan JavaScript birlikte çalışma çağrıları

Daha fazla bilgi için bkz. ASP.NET Core Blazor JavaScript birlikte çalışabilirliği (JSbirlikte çalışma).

Ek kaynaklar