ASP.NET Core Blazor JavaScript birlikte çalışabilirliği (JS interop)

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.

Uyarı

ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. 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.

Blazor uygulaması JavaScript (JS) işlevlerini .NET yöntemlerinden ve .NET yöntemlerini JS işlevlerinden çağırabilir. Bu senaryolar JavaScript birlikte çalışabilirliği (JS interop) olarak adlandırılır.

Aşağıdaki makalelerde daha fazla JS interop rehberliği sağlanır:

Not

JavaScript birlikte çalışma API'si [JSImport]/[JSExport] , .NET 7 veya sonraki sürümlerde ASP.NET Core'daki istemci tarafı bileşenleri için kullanılabilir.

Daha fazla bilgi için bkz . JavaScript JSImport/JSExport ASP.NET Core Blazorile birlikte çalışma.

Güvenilmeyen verilerle etkileşimli sunucu bileşenleri için sıkıştırma

Varsayılan olarak etkin olan sıkıştırma ile güvenilmeyen kaynaklardan veri işleyen güvenli (kimliği doğrulanmış/yetkilendirilmiş) etkileşimli sunucu tarafı bileşenleri oluşturmaktan kaçının. Güvenilmeyen kaynaklar arasında yol parametreleri, sorgu dizeleri, birlikte çalışma verileri JS ve üçüncü taraf bir kullanıcının denetleyebileceği diğer veri kaynakları (veritabanları, dış hizmetler) bulunur. Daha fazla bilgi için bkz . ASP.NET Core BlazorSignalR kılavuzu ve ASP.NET Core Blazor etkileşimli sunucu tarafı işleme için tehdit azaltma kılavuzu.

JavaScript birlikte çalışma özetleri ve özellikler paketi

@microsoft/dotnet-js-interop Paket (npmjs.com) (Microsoft.JSInterop NuGet paketi), .NET ile JavaScript (JS) kodu arasında birlikte çalışma için soyutlamalar ve özellikler sağlar. Başvuru kaynağı GitHub deposunda ( klasör) kullanılabilirdotnet/aspnetcore./src/JSInterop Daha fazla bilgi için GitHub deposunun README.md dosyasına bakın.

Not

.NET başvuru kaynağına yönelik belge bağlantıları genellikle deponun varsayılan dalını yükler ve bu dal .NET'in sonraki sürümü için geçerli geliştirmeyi temsil eder. Belirli bir sürümün etiketini seçmek için Dalları veya etiketleri değiştir açılan listesini kullanın. Daha fazla bilgi için bkz. ASP.NET Core kaynak kodunun sürüm etiketini seçme (dotnet/AspNetCore.Docs #26205).

TypeScript'te birlikte çalışma betikleri yazmak JS için ek kaynaklar:

DOM ile etkileşim

DoM'un sesini yalnızca nesne ile etkileşim kurmadığında JavaScript (JS) ile Blazorsessize alma. Blazor DOM gösterimlerini korur ve DOM nesneleriyle doğrudan etkileşim kurar. Blazor tarafından işlenen öğe doğrudan JS kullanılarak veya JS Interop yoluyla dışarıdan değiştirilirse, DOM artık Blazor'ın iç gösterimini eşleştiremeyebilir ve bu da tanımsız bir davranışla sonuçlanabilir. Tanımsız davranış öğelerin veya işlevlerinin gösterimini etkileyebilir ama aynı zamanda uygulama veya sunucu için güvenlik risklerine de neden olabilir.

Bu rehber yalnızca kendi JS interop kodunuz için değil, aynı zamanda Bootstrap JS ve jQuery gibi üçüncü taraflarca sağlananlar da dahil olmak üzere uygulamanın kullandığı tüm JS kitaplıkları için geçerlidir.

Birkaç belge örneğinde, JS interop örneğin bir parçası olarak yalnızca tanıtım amacıyla bir öğeyi değiştirmek için kullanılmıştır. Böyle durumlarda metinde bir uyarı görüntülenir.

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

İşlev türünde bir alana sahip JavaScript sınıfı

İşlev türündeki bir alana sahip javascript sınıfı birlikte çalışma tarafından BlazorJS desteklenmez. Sınıflarda Javascript işlevlerini kullanın.

Desteklenmiyor: GreetingHelpers.sayHello Aşağıdaki sınıfta bir tür işlevi alanı olarak birlikte çalışma tarafından BlazorJS bulunmaz ve C# kodundan yürütülemez:

export class GreetingHelpers {
  sayHello = function() {
    ...
  }
}

Desteklenir: GreetingHelpers.sayHello İşlev olarak aşağıdaki sınıfta desteklenir:

export class GreetingHelpers {
  sayHello() {
    ...
  }
}

Ok işlevleri de desteklenir:

export class GreetingHelpers {
  sayHello = () => {
    ...
  }
}

Satır içi olay işleyicilerinden kaçının

JavaScript işlevi doğrudan bir satır içi olay işleyicisinden çağrılabilir. Aşağıdaki örnekte, alertUser düğme kullanıcı tarafından seçildiğinde çağrılan bir JavaScript işlevidir:

<button onclick="alertUser">Click Me!</button>

Ancak, satır içi olay işleyicilerinin kullanımı JavaScript işlevlerini çağırmak için kötü bir tasarım seçeneğidir :

Aşağıdaki örnekte gösterildiği gibi, ile addEventListenerJavaScript'te işleyicileri atayan yaklaşımlar yerine satır içi olay işleyicilerinden kaçınmanızı öneririz:

AlertUser.razor.js:

export function alertUser() {
  alert('The button was selected!');
}

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

AlertUser.razor:

@page "/alert-user"
@implements IAsyncDisposable
@inject IJSRuntime JS

<h1>Alert User</h1>

<p>
    <button id="btn">Click Me!</button>
</p>

@code {
    private IJSObjectReference? module;

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

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

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

Daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın:

Zaman uyumsuz JavaScript çağrıları

JS birlikte çalışma çağrıları, çağrılan kodun zaman uyumlu veya zaman uyumsuz olmasına bakılmaksızın zaman uyumsuzdur. Çağrılar, bileşenlerin sunucu tarafı ve istemci tarafı işleme modelleri arasında uyumlu olduğundan emin olmak için zaman uyumsuz hale getirilir. Sunucu tarafı işlemeyi benimserken, JS birlikte çalışma çağrıları bir ağ bağlantısı üzerinden gönderildiği için zaman uyumsuz olmalıdır. yalnızca istemci tarafı işlemeyi benimseyen uygulamalar için zaman uyumlu JS birlikte çalışma çağrıları desteklenir.

Nesne serileştirme

Blazor serileştirme için, aşağıdaki gereksinimler ve varsayılan davranışlarla System.Text.Json kullanır:

  • Türlerin varsayılan oluşturucusu olmalıdır, get/set erişimciler genel olmalıdır ve alanlar hiçbir zaman serileştirilmez.
  • Mevcut bileşen kitaplıklarının bozulmasını, performans ve güvenlik etkilerini, ayrıca güvenilirliğin azalmasını önlemek için genel varsayılan serileştirme özelleştirilemez.
  • .NET üye adlarını seri hale getirerek küçük harf JSON anahtar adları elde edebilirsiniz.
  • JSON, karışık büyük/küçük harfe izin veren C# örnekleri olarak JsonElement seri durumdan çıkarılır. C# modeli özelliklerine atama için iç atama, JSON anahtar adları ile C# özellik adları arasındaki büyük/küçük harf farklarına rağmen beklendiği gibi çalışır.
  • gibi KeyValuePairkarmaşık çerçeve türleri, yayımlama sırasında IL Düzelticisi tarafından kırpılabilir ve birlikte çalışma için JS mevcut olmayabilir. IL Düzeltici'nin kırpıp kaldırdığını türler için özel türler oluşturmanızı öneririz.
  • BlazorC# kaynak oluşturma da dahil olmak üzere her zaman JSON serileştirme için yansımayı kullanır. false Uygulamanın proje dosyasında olarak ayarlanmasıJsonSerializerIsReflectionEnabledByDefault, serileştirme denendiğinde hatayla sonuçlanır.

Özel serileştirme için JsonConverter API'si kullanılabilir. Mevcut veri türünde varsayılan serileştirmeyi geçersiz kılmak için özelliklere [JsonConverter] özniteliğiyle not eklenebilir.

Daha fazla bilgi için .NET belgelerinde aşağıdaki kaynaklara bakın:

Blazor, bayt dizilerinin Base64'e kodlanmasını/kodunun çözülmesini önleyen iyileştirilmiş bayt dizisi JS interop'u destekler. Uygulama özel serileştirme uygulayabilir ve sonuçta elde edilen baytları geçirir. Daha fazla bilgi için bkz. ASP.NET Core Blazor'da .NET yöntemlerinden JavaScript işlevlerini çağırma.

Yüksek hacimli .NET nesneleri hızla serileştirildiğinde ya da büyük .NET nesnelerinin veya birçok .NET nesnesinin serileştirilmesi gerektiğinde Blazor hazırlaması geri alınmış JS interop'u destekler. Daha fazla bilgi için bkz. ASP.NET Core Blazor'da .NET yöntemlerinden JavaScript işlevlerini çağırma.

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

Bileşen elden çıkarma sırasında DOM temizleme görevleri için birlikte çalışma kodu yürütmeyin JS . Bunun yerine, aşağıdaki nedenlerle istemcide JavaScript (JS) desenini kullanınMutationObserver:

  • Temizleme kodunuz içinde yürütülürken bileşen DOM'dan Dispose{Async}kaldırılmış olabilir.
  • Sunucu tarafı işleme sırasında işleyici, Blazor temizleme kodunuz içinde Dispose{Async}yürütülürken çerçeve tarafından atılmış olabilir.

Desen, MutationObserver bir öğe DOM'dan kaldırıldığında bir işlevi çalıştırmanıza olanak tanır.

Aşağıdaki örnekte bileşeni DOMCleanup :

  • <div> ile bir id cleanupDiviçerir. <div> Bileşen DOM'dan kaldırıldığında öğesi, bileşenin DOM işaretlemesiyle birlikte rest DOM'dan kaldırılır.
  • dosyasından sınıfını DOMCleanupJS DOMCleanup.razor.js yükler ve geri çağırmayı ayarlamak MutationObserver için işlevini çağırır.createObserver Bu görevler yaşam döngüsü yönteminde OnAfterRenderAsyncgerçekleştirilir.

DOMCleanup.razor:

@page "/dom-cleanup"
@implements IAsyncDisposable
@inject IJSRuntime JS

<h1>DOM Cleanup Example</h1>

<div id="cleanupDiv"></div>

@code {
    private IJSObjectReference? module;

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

            await module.InvokeVoidAsync("DOMCleanup.createObserver");
        }
    }

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

Aşağıdaki örnekte, MutationObserver bir DOM değişikliği her gerçekleştiğinde geri çağırma yürütülür. Deyimi hedef öğenin () kaldırıldığınıif (targetRemoved) { ... } (cleanupDiv) onayladığında if temizleme kodunuzu yürütür. Temizleme kodunuz yürütülürken bellek sızıntısını MutationObserver önlemek için bağlantısının kesilmesi ve silinmesi önemlidir.

DOMCleanup.razor.js önceki DOMCleanup bileşenle yan yana yerleştirilir:

export class DOMCleanup {
  static observer;

  static createObserver() {
    const target = document.querySelector('#cleanupDiv');

    this.observer = new MutationObserver(function (mutations) {
      const targetRemoved = mutations.some(function (mutation) {
        const nodes = Array.from(mutation.removedNodes);
        return nodes.indexOf(target) !== -1;
      });

      if (targetRemoved) {
        // Cleanup resources here
        // ...

        // Disconnect and delete MutationObserver
        this.observer && this.observer.disconnect();
        delete this.observer;
      }
    });

    this.observer.observe(target.parentNode, { childList: true });
  }
}

window.DOMCleanup = DOMCleanup;

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

Bu bölüm yalnızca sunucu tarafı uygulamalar için geçerlidir.

Bağlantı hattı kesildikten sonra SignalR JavaScript (JS) birlikte çalışma çağrıları düzenlenemez. Bileşenin atılması sırasında veya başka bir zamanda bir bağlantı hattı olmadığında, aşağıdaki yöntem çağrıları başarısız olur ve bağlantı hattının bağlantısının kesildiğini belirten bir JSDisconnectedExceptionileti kaydeder:

Günlüğe kaydetmeyi JSDisconnectedException veya özel bilgileri günlüğe kaydetmeyi önlemek için deyimindeki try-catch özel durumu yakalayın.

Aşağıdaki bileşen elden çıkarma örneği için:

  • Bileşen IAsyncDisposable gerçekleştirir.
  • objInstance bir IJSObjectReference...
  • JSDisconnectedException yakalanmış ve günlüğe kaydedilmemiş.
  • İsteğe bağlı olarak, deyimindeki catch özel bilgileri istediğiniz günlük düzeyinde günlüğe kaydedebilirsiniz. Aşağıdaki örnek, geliştiricinin bileşen elden çıkarma sırasında bağlantı hatlarının ne zaman veya nerede kesileceğiyle ilgilenmediği varsayıldığından özel bilgileri günlüğe kaydetmez.
async ValueTask IAsyncDisposable.DisposeAsync()
{
    try
    {
        if (objInstance is not null)
        {
            await objInstance.DisposeAsync();
        }
    }
    catch (JSDisconnectedException)
    {
    }
}

Bir bağlantı hattı kaybolduktan sonra kendi JS nesnelerinizi temizlemeniz veya istemcide başka JS bir kod yürütmeniz gerekiyorsa, istemcide içindeki JS deseni MutationObserver kullanın. Desen, MutationObserver bir öğe DOM'dan kaldırıldığında bir işlevi çalıştırmanıza olanak tanır.

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

Önbelleğe alınan JavaScript dosyaları

JavaScript (JS) dosyaları ve diğer statik varlıklar Developmentortamında geliştirme sırasında genel olarak istemcilerde önbelleğe alınmaz. Geliştirme sırasında statik varlık istekleri no-cache değerine sahip Cache-Control üst bilgisi veya sıfır (0) değerine sahip max-age içerir.

Production ortamında üretim sırasında JS dosyaları genellikle istemciler tarafından önbelleğe alınır.

Tarayıcılarda istemci tarafı önbelleğini devre dışı bırakmak için geliştiriciler genellikle aşağıdaki yaklaşımlardan birini benimser:

  • Tarayıcıların geliştirici araçları konsolu açık olduğunda önbelleği devre dışı bırakma. Yönergeler, her tarayıcı bakımcısının geliştirici araçları belgelerinde bulunabilir:
  • Sunucudan JS dosyalarını yeniden yüklemek için Blazor uygulamasının herhangi bir web sayfasında el ile tarayıcı yenilemesi gerçekleştirin. ASP.NET Core'un HTTP Önbellek Ara Yazılımı, istemci tarafından gönderilen geçerli bir önbelleğe almama Cache-Control üst bilgisini her zaman kabul eder.

Daha fazla bilgi için bkz.

JavaScript birlikte çalışma çağrılarında boyut sınırları

Bu bölüm yalnızca sunucu tarafı uygulamalarındaki etkileşimli bileşenler için geçerlidir. İstemci tarafı bileşenleri için, çerçeve JavaScript (JS) birlikte çalışma girişlerinin ve çıkışlarının boyutuna bir sınır getirmez.

Sunucu tarafı uygulamalarındaki etkileşimli bileşenler için, JS istemciden sunucuya veri geçiren birlikte çalışma çağrılarının boyutu, hub yöntemleri için izin verilen en yüksek gelen SignalR ileti boyutuyla sınırlıdır ve bu boyut tarafından zorlanır HubOptions.MaximumReceiveMessageSize (varsayılan olarak: 32 KB). JShata vermekten daha MaximumReceiveMessageSize büyük .NET SignalR iletilerine. Çerçeve, hub'dan istemciye ileti SignalR boyutuna bir sınır getirmez. Boyut sınırı, hata iletileri ve ileti boyutu sınırlarıyla ilgili yönergeler hakkında daha fazla bilgi için bkz . ASP.NET Çekirdek BlazorSignalR kılavuzu.

Uygulamanın nerede çalıştığını belirleme

Uygulamanın birlikte çalışma çağrıları için kodun nerede çalıştığını bilmesi uygunsa, bileşenin WebAssembly'deki tarayıcı bağlamında yürütülüp yürütülmediğini belirlemek için JS kullanın OperatingSystem.IsBrowser .