ASP.NET Core'da görüntü ve belge görüntüleme 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.

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.

Bu makalede, uygulamalarda görüntü ve belge görüntüleme yaklaşımları Blazor açıklanmaktadır.

Bu makaledeki örnekler, örnek uygulamalarda inceleme ve kullanım Blazor için kullanılabilir:

dotnet/blazor-samplesGitHub deposu: (8.0 veya üzeri), BlazorSample_Server (7.0 veya öncesi) veya BlazorSample_WebAssemblyadlı BlazorSample_BlazorWebApp uygulamaya gidin.

Dinamik olarak görüntü kaynağı ayarlama

Aşağıdaki örnekte, C# alanıyla bir görüntünün kaynağının dinamik olarak nasıl ayarlanacağı gösterilmektedir.

Bu bölümdeki örnekte , image2.pngve image3.pngadlı image1.pngüç görüntü dosyası kullanılır. Görüntüler, uygulamanın web kökünde ()wwwroot adlı images bir klasöre yerleştirilir. Klasörün kullanımı images yalnızca gösterim amaçlıdır. Varlıkları doğrudan klasörden sunma dahil olmak üzere, statik varlıkları tercih ettiğiniz herhangi bir klasör düzeninde wwwroot düzenleyebilirsiniz.

Aşağıdaki ShowImage1 bileşeninde:

  • Görüntünün kaynağı (src), C# dilinde değerine imageSource dinamik olarak ayarlanır.
  • yöntemi, ShowImage yöntemine imageSource geçirilen bir görüntü id bağımsız değişkenine göre alanı güncelleştirir.
  • İşlenen düğmeler, klasördeki ShowImage kullanılabilir üç görüntünün images her biri için bir görüntü bağımsız değişkeniyle yöntemini çağırır. Dosya adı, yöntemine geçirilen bağımsız değişken kullanılarak oluşturulur ve klasördeki images üç görüntüden biriyle eşleşir.

ShowImage1.razor:

@page "/show-image-1"

<PageTitle>Show Image 1</PageTitle>

<h1>Show Image Example 1</h1>

@if (imageSource is not null)
{
    <p>
        <img src="@imageSource" />
    </p>
}

@for (var i = 1; i <= 3; i++)
{
    var imageId = i;
    <button @onclick="() => ShowImage(imageId)">
        Image @imageId
    </button>
}

@code {
    private string? imageSource;

    private void ShowImage(int id) => imageSource = $"images/image{id}.png";
}
@page "/show-image-1"

<PageTitle>Show Image 1</PageTitle>

<h1>Show Image Example 1</h1>

@if (imageSource is not null)
{
    <p>
        <img src="@imageSource" />
    </p>
}

@for (var i = 1; i <= 3; i++)
{
    var imageId = i;
    <button @onclick="() => ShowImage(imageId)">
        Image @imageId
    </button>
}

@code {
    private string? imageSource;

    private void ShowImage(int id) => imageSource = $"images/image{id}.png";
}
@page "/show-image-1"

<h1>Dynamic Image Source Example</h1>

@if (imageSource is not null)
{
    <p>
        <img src="@imageSource" />
    </p>
}

@for (var i = 1; i <= 3; i++)
{
    var imageId = i;
    <button @onclick="() => ShowImage(imageId)">
        Image @imageId
    </button>
}

@code {
    private string? imageSource;

    private void ShowImage(int id)
    {
        imageSource = $"images/image{id}.png";
    }
}
@page "/show-image-1"

<h1>Dynamic Image Source Example</h1>

@if (imageSource is not null)
{
    <p>
        <img src="@imageSource" />
    </p>
}

@for (var i = 1; i <= 3; i++)
{
    var imageId = i;
    <button @onclick="() => ShowImage(imageId)">
        Image @imageId
    </button>
}

@code {
    private string? imageSource;

    private void ShowImage(int id)
    {
        imageSource = $"images/image{id}.png";
    }
}

Yukarıdaki örnekte görüntünün kaynak verilerini tutmak için bir C# alanı kullanılır, ancak verileri tutmak için bir C# özelliği de kullanabilirsiniz.

Önceki for döngü örneğinde olduğu gibi i bir lambda ifadesinde doğrudan bir döngü değişkeni kullanmaktan kaçının. Aksi takdirde, aynı değişken tüm lambda ifadeleri tarafından kullanılır ve bu da tüm lambdalarda aynı değerin kullanılmasına neden olur. Değişkenin değerini yerel değişkende yakalayın. Yukarıdaki örnekte:

  • Döngü değişkeni i öğesine imageIdatanır.
  • imageId lambda ifadesinde kullanılır.

Alternatif olarak, önceki sorundan muzdarip olmayan ile Enumerable.Rangebir foreach döngü kullanın:

@foreach (var imageId in Enumerable.Range(1, 3))
{
    <button @onclick="() => ShowImage(imageId)">
        Image @imageId
    </button>
}

Olay işlemeye sahip lambda ifadeleri hakkında daha fazla bilgi için bkz . ASP.NET Core Blazor olay işleme.

Görüntü veya belge verilerini akışla aktarma

Pdf gibi bir görüntü veya başka bir belge türü, dosyayı genel URL'de barındırmak yerine 'nin akış birlikte çalışma özellikleri kullanılarak Blazordoğrudan istemciye iletilebilir.

Bu bölümdeki örnek, JavaScript (JS) birlikte çalışma kullanarak kaynak verileri akışla aktarıyor. Aşağıdaki setSourceJS işlev:

  • Şu öğeler için içerik akışı yapmak için kullanılabilir: , , , , , <link>, <object>, <script><style>ve <track>. <img><iframe><embed><body>
  • Dosyanın içeriğini, belge için bir veri akışını, içerik türünü ve görüntüleme öğesinin başlığını görüntülemek için bir öğeyi kabul eder id .

İşlev:

  • Sağlanan akışı bir ArrayBufferiçine okur.
  • blob'un ArrayBufferiçerik türünü ayarlayarak sarmalamak için bir Blob oluşturur.
  • Belgenin gösterileceği adres olarak hizmet vermek üzere bir nesne URL'si oluşturur.
  • parametresinden öğenin başlığını (title) title ve oluşturulan nesne URL'sinden öğenin kaynağını (src) ayarlar.
  • Bellek sızıntılarını önlemek için işlev, öğe kaynağı (load olay) yükledikten sonra nesne URL'sini atmak için çağırırrevokeObjectURL.
<script>
  window.setSource = async (elementId, stream, contentType, title) => {
    const arrayBuffer = await stream.arrayBuffer();
    let blobOptions = {};
    if (contentType) {
      blobOptions['type'] = contentType;
    }
    const blob = new Blob([arrayBuffer], blobOptions);
    const url = URL.createObjectURL(blob);
    const element = document.getElementById(elementId);
    element.title = title;
    element.onload = () => {
      URL.revokeObjectURL(url);
    }
    element.src = url;
  }
</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 ShowImage2 bileşen:

  • ve System.Net.Http.HttpClient Microsoft.JSInterop.IJSRuntimeiçin hizmetler ekler.
  • <img> Görüntü görüntülemek için bir etiket içerir.
  • GetImageStreamAsync Bir görüntü için almak için bir Stream C# yöntemi vardır. Üretim uygulaması, belirli bir kullanıcıyı temel alan bir görüntüyü dinamik olarak oluşturabilir veya depolama alanından bir görüntü alabilir. Aşağıdaki örnek GitHub deposu için .NET avatarını dotnet alır.
  • Düğmenin kullanıcı tarafından seçilmesinde tetiklenen bir SetImageAsync yöntemi vardır. SetImageAsync aşağıdaki adımları gerçekleştirir:
    • 'den GetImageStreamAsyncöğesini Stream alır.
    • görüntü verilerinin Stream istemciye akışına izin veren bir DotNetStreamReferenceiçinde sarmalar.
    • İstemcideki setSource verileri kabul eden JavaScript işlevini çağırır.

Not

Sunucu tarafı uygulamalar istekte bulunmak için ayrılmış HttpClient bir hizmet kullandığından, sunucu tarafı Blazor uygulamasının geliştiricisi hizmeti kaydetmek için herhangi bir HttpClient eylem gerçekleştirmez. Uygulama bir proje şablonundan Blazor oluşturulduğunda istemci tarafı uygulamaların varsayılan HttpClient hizmet kaydı vardır. HttpClient İstemci tarafı uygulamasının Program dosyasında bir hizmet kaydı yoksa, ekleyerek builder.Services.AddHttpClient();bir hizmet kaydı sağlayın. Daha fazla bilgi için, bkz. ASP.NET Core'da IHttpClientFactory kullanarak HTTP isteği yapma.

ShowImage2.razor:

@page "/show-image-2"
@inject HttpClient Http
@inject IJSRuntime JS

<PageTitle>Show Image 2</PageTitle>

<h1>Show Image Example 2</h1>

<button @onclick="SetImageAsync">
    Set Image
</button>

<div class="p-3">
    <img id="avatar" />
</div>

@code {
    private async Task<Stream> GetImageStreamAsync() => 
        await Http.GetStreamAsync("https://avatars.githubusercontent.com/u/9141961");

    private async Task SetImageAsync()
    {
        var imageStream = await GetImageStreamAsync();
        var strRef = new DotNetStreamReference(imageStream);
        await JS.InvokeVoidAsync("setSource", "avatar", strRef, "image/png", 
            ".NET GitHub avatar");
    }
}
@page "/show-image-2"
@inject HttpClient Http
@inject IJSRuntime JS

<PageTitle>Show Image 2</PageTitle>

<h1>Show Image Example 2</h1>

<button @onclick="SetImageAsync">
    Set Image
</button>

<div class="p-3">
    <img id="avatar" />
</div>

@code {
    private async Task<Stream> GetImageStreamAsync() => 
        await Http.GetStreamAsync("https://avatars.githubusercontent.com/u/9141961");

    private async Task SetImageAsync()
    {
        var imageStream = await GetImageStreamAsync();
        var strRef = new DotNetStreamReference(imageStream);
        await JS.InvokeVoidAsync("setSource", "avatar", strRef, "image/png", 
            ".NET GitHub avatar");
    }
}
@page "/show-image-2"
@inject HttpClient Http
@inject IJSRuntime JS

<h1>Show Image Example 2</h1>

<button @onclick="SetImageAsync">
    Set Image
</button>

<div class="p-3">
    <img id="avatar" />
</div>

@code {
    private async Task<Stream> GetImageStreamAsync()
    {
        return await Http.GetStreamAsync(
            "https://avatars.githubusercontent.com/u/9141961");
    }

    private async Task SetImageAsync()
    {
        var imageStream = await GetImageStreamAsync();
        var strRef = new DotNetStreamReference(imageStream);
        await JS.InvokeVoidAsync("setSource", "avatar", strRef, "image/png", 
            ".NET GitHub avatar");
    }
}
@page "/show-image-2"
@inject HttpClient Http
@inject IJSRuntime JS

<h1>Show Image Example 2</h1>

<button @onclick="SetImageAsync">
    Set Image
</button>

<div class="p-3">
    <img id="avatar" />
</div>

@code {
    private async Task<Stream> GetImageStreamAsync()
    {
        return await Http.GetStreamAsync(
            "https://avatars.githubusercontent.com/u/9141961");
    }

    private async Task SetImageAsync()
    {
        var imageStream = await GetImageStreamAsync();
        var strRef = new DotNetStreamReference(imageStream);
        await JS.InvokeVoidAsync("setSource", "avatar", strRef, "image/png", 
            ".NET GitHub avatar");
    }
}

Aşağıdaki ShowFile bileşen bir öğeye (files/quote.txtMDN belgeleri) bir metin dosyası () veya PDF <iframe> dosyası (files/quote.pdf) yükler.

Dikkat

Aşağıdaki örnekteki <iframe> öğesinin kullanımı güvenlidir ve güvenilir bir kaynak olan uygulamadan içerik yüklendiğinden korumalı alan gerektirmez.

Güvenilmeyen bir kaynaktan veya kullanıcı girişinden içerik yüklerken, yanlış uygulanan <iframe> bir öğe güvenlik açıkları oluşturma riski taşır.

ShowFile.razor:

@page "/show-file"
@inject NavigationManager Navigation
@inject HttpClient Http
@inject IJSRuntime JS

<PageTitle>Show File</PageTitle>

<div class="d-flex flex-column">
    <h1>Show File Example</h1>
    <div class="mb-4">
        <button @onclick="@(() => ShowFileAsync("files/quote.txt", 
                "General Ravon quote (text file)"))">
            Show text ('quote.txt')
        </button>
        <button @onclick="@(() => ShowFileAsync("files/quote.pdf", 
                "General Ravon quote (PDF file)"))">
            Show PDF ('quote.pdf')
        </button>
    </div>
    <iframe id="iframe" style="height: calc(100vh - 200px)" />
</div>

@code
{
    private async Task<(Stream, string?)> DownloadFileAsync(string url)
    {
        var absoluteUrl = Navigation.ToAbsoluteUri(url);
        Console.WriteLine($"Downloading file from {absoluteUrl}");

        var response = await Http.GetAsync(absoluteUrl);
        string? contentType = null;

        if (response.Content.Headers.TryGetValues("Content-Type", out var values))
        {
            contentType = values.FirstOrDefault();
        }

        return (await response.Content.ReadAsStreamAsync(), contentType);
    }

    private async Task ShowFileAsync(string url, string title)
    {
        var (fileStream, contentType) = await DownloadFileAsync(url);
        var strRef = new DotNetStreamReference(fileStream);
        await JS.InvokeVoidAsync("setSource", "iframe", strRef, contentType, title);
    }
}
@page "/show-file"
@inject NavigationManager Navigation
@inject HttpClient Http
@inject IJSRuntime JS

<PageTitle>Show File</PageTitle>

<div class="d-flex flex-column">
    <h1>Show File Example</h1>
    <div class="mb-4">
        <button @onclick="@(() => ShowFileAsync("files/quote.txt", 
                "General Ravon quote (text file)"))">
            Show text ('quote.txt')
        </button>
        <button @onclick="@(() => ShowFileAsync("files/quote.pdf", 
                "General Ravon quote (PDF file)"))">
            Show PDF ('quote.pdf')
        </button>
    </div>
    <iframe id="iframe" style="height: calc(100vh - 200px)" />
</div>

@code
{
    private async Task<(Stream, string?)> DownloadFileAsync(string url)
    {
        var absoluteUrl = Navigation.ToAbsoluteUri(url);
        Console.WriteLine($"Downloading file from {absoluteUrl}");

        var response = await Http.GetAsync(absoluteUrl);
        string? contentType = null;

        if (response.Content.Headers.TryGetValues("Content-Type", out var values))
        {
            contentType = values.FirstOrDefault();
        }

        return (await response.Content.ReadAsStreamAsync(), contentType);
    }

    private async Task ShowFileAsync(string url, string title)
    {
        var (fileStream, contentType) = await DownloadFileAsync(url);
        var strRef = new DotNetStreamReference(fileStream);
        await JS.InvokeVoidAsync("setSource", "iframe", strRef, contentType, title);
    }
}
@page "/show-file"
@inject NavigationManager NavigationManager
@inject HttpClient Http
@inject IJSRuntime JS

<div class="d-flex flex-column">
    <h1>Show File Example</h1>
    <div class="mb-4">
        <button @onclick="@(() => ShowFileAsync("files/quote.txt", 
                "General Ravon quote (text file)"))">
            Show text ('quote.txt')
        </button>
        <button @onclick="@(() => ShowFileAsync("files/quote.pdf", 
                "General Ravon quote (PDF file)"))">
            Show PDF ('quote.pdf')
        </button>
    </div>
    <iframe id="iframe" style="height: calc(100vh - 200px)" />
</div>

@code
{
    private async Task<(Stream, string?)> DownloadFileAsync(string url)
    {
        var absoluteUrl = NavigationManager.ToAbsoluteUri(url);
        Console.WriteLine($"Downloading file from {absoluteUrl}");

        var response = await Http.GetAsync(absoluteUrl);
        string? contentType = null;

        if (response.Content.Headers.TryGetValues("Content-Type", out var values))
        {
            contentType = values.FirstOrDefault();
        }

        return (await response.Content.ReadAsStreamAsync(), contentType);
    }

    private async Task ShowFileAsync(string url, string title)
    {
        var (fileStream, contentType) = await DownloadFileAsync(url);
        var strRef = new DotNetStreamReference(fileStream);
        await JS.InvokeVoidAsync("setSource", "iframe", strRef, contentType, title);
    }
}
@page "/show-file"
@inject NavigationManager NavigationManager
@inject HttpClient Http
@inject IJSRuntime JS

<div class="d-flex flex-column">
    <h1>Show File Example</h1>
    <div class="mb-4">
        <button @onclick="@(() => ShowFileAsync("files/quote.txt", 
                "General Ravon quote (text file)"))">
            Show text ('quote.txt')
        </button>
        <button @onclick="@(() => ShowFileAsync("files/quote.pdf", 
                "General Ravon quote (PDF file)"))">
            Show PDF ('quote.pdf')
        </button>
    </div>
    <iframe id="iframe" style="height: calc(100vh - 200px)" />
</div>

@code
{
    private async Task<(Stream, string?)> DownloadFileAsync(string url)
    {
        var absoluteUrl = NavigationManager.ToAbsoluteUri(url);
        Console.WriteLine($"Downloading file from {absoluteUrl}");

        var response = await Http.GetAsync(absoluteUrl);
        string? contentType = null;

        if (response.Content.Headers.TryGetValues("Content-Type", out var values))
        {
            contentType = values.FirstOrDefault();
        }

        return (await response.Content.ReadAsStreamAsync(), contentType);
    }

    private async Task ShowFileAsync(string url, string title)
    {
        var (fileStream, contentType) = await DownloadFileAsync(url);
        var strRef = new DotNetStreamReference(fileStream);
        await JS.InvokeVoidAsync("setSource", "iframe", strRef, contentType, title);
    }
}

Ek kaynaklar