I'm having trouble writing the code to downloading the page.

Saeed Pooladzadeh 251 Reputation points
2024-09-25T11:59:28.83+00:00

I'm attempting to create a small application that converts image formats to SVG. And bellow comes the code:

 
@page "/"
@using System.Drawing
@using System.Drawing.Imaging
@using System.IO
@using System.Threading.Tasks
@using Microsoft.AspNetCore.Components.Forms
@using System.Text
@using Microsoft.AspNetCore.Mvc
@using Microsoft.AspNetCore.Http
@inject IHttpContextAccessor HttpContextAccessor
@inject NavigationManager NavigationManager
@using System
@using System.Net
@* @using Microsoft.AspNetCore.Mvc
@using Claue3_Haiko *@






<h3>Bitmap to SVG Converter</h3>

<InputFile OnChange="@HandleFileUploadAsync" />

@* progress-bar *@

@if (isConverting)
{
    <div class="progress mt-3">
        <div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 100%"></div>
    </div>
}


@if (svgContent != null)
{
    <div>
        <h4>Generated SVG:</h4>
        <div>@((MarkupString)svgContent)</div>
    </div>

    <div>

        <button class="btn btn-primary mt-3" @onclick="DownloadSvg">Download SVG</button>
    </div>
}

@code {
    private string svgContent = null!;
    private bool isConverting = false;



    // uploading the image

    private async Task HandleFileUploadAsync(InputFileChangeEventArgs e)
    {
        var file = e.GetMultipleFiles(1).FirstOrDefault();
        if (file != null)
        {
            isConverting = true;
            StateHasChanged();


            using var stream = new MemoryStream();
            await file.OpenReadStream().CopyToAsync(stream);
            stream.Seek(0, SeekOrigin.Begin);

            var bitmap = new Bitmap(stream);
            svgContent = ConvertBitmapToSvg(bitmap);

            isConverting = false;
            StateHasChanged();

        }
    }

    //converting bitmap to svg

    private string ConvertBitmapToSvg(Bitmap bitmap)
    {
        var width = bitmap.Width;
        var height = bitmap.Height;

        var svg = new StringBuilder();
        svg.AppendLine($"<svg width='{width}' height='{height}' xmlns='http://www.w3.org/2000/svg'>");

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                var color = bitmap.GetPixel(x, y);
                var hexColor = $"#{color.R:X2}{color.G:X2}{color.B:X2}";
                svg.AppendLine($"<rect x='{x}' y='{y}' width='1' height='1' fill='{hexColor}' />");
            }
        }

        svg.AppendLine("</svg>");
        return svg.ToString();
    }

    // Downloading the SVG image

    private void DownloadSvg()
{
    byte[] svgBytes = Encoding.UTF8.GetBytes(svgContent);
    var fileName = "convertedImage.svg";

    var base64 = Convert.ToBase64String(svgBytes);
    var dataUrl = $"data:image/svg+xml;base64,{base64}";

    NavigationManager.NavigateTo(dataUrl, true);
}

}

But the issue arises when the user clicks the button to download the.SVG image.

This part:

    // Downloading the svg image

    private void DownloadSvg()
{
    byte[] svgBytes = Encoding.UTF8.GetBytes(svgContent);
    var fileName = "convertedImage.svg";

    var base64 = Convert.ToBase64String(svgBytes);
    var dataUrl = $"data:image/svg+xml;base64,{base64}";

    NavigationManager.NavigateTo(dataUrl, true);
}

Please inform me.

Thanks,

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,609 questions
Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,596 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Ping Ni-MSFT 4,720 Reputation points Microsoft Vendor
    2024-09-26T02:17:49.5733333+00:00

    Hi Saeed Pooladzadeh,

    The NavigationManager.NavigateTo is designed to handle page navigation, not file downloads.

    You can follow the official document to learn how to file download in Blazor Server

    This article covers approaches for the following scenarios, where a file shouldn't be opened by a browser but downloaded and saved on the client:

    For example:

    1.Modify Razor Component code

    @inject IJSRuntime JS
    private async Task DownloadSvg()
    {
        byte[] svgBytes = Encoding.UTF8.GetBytes(svgContent);
        var fileName = "convertedImage.svg";
        var base64 = Convert.ToBase64String(svgBytes);
        var dataUrl = $"data:image/svg+xml;base64,{base64}";
      
        await JS.InvokeVoidAsync("triggerDownload", dataUrl, fileName);
    }
    

    2.Add the JavaScript function in your _Host.cshtml(Assume you are using .NET 7 Blazor Server App)

    <body>
        //.....
        <script src="_framework/blazor.server.js"></script>
        <script>
            function triggerDownload(dataUrl, fileName) {
                const link = document.createElement('a');
                link.href = dataUrl;
                link.download = fileName;
                link.click();
            }
        </script>
    </body>
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Rena


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.