Unable to bind the selected image file in Blazor file upload

RAMAN RAGAVAN 51 Reputation points
2023-02-04T02:38:07.29+00:00

"This question is updated with minimal sample as my old question doesnt give more info"

I am learning blazor and c# fundas with a simple app.This app will allow you tobrowse all kind of files including images.As all kind files we can browse, i need a seperate classfor images only so when ever user select file, first class-BrowserFileWithStatus list will trigger the second class-MediaVariantUI (lists)

class 1-BrowserFileWithStatus - list of this class NOT  use to bind to the UI

class 2-MediaVariantUI- list of this class will use to bind to the UI

I am able to bind the file name but How i can bind the images in mud card.I dont want to disturb my first class i need to asign my images to second class list.How can I do that? below is my classes and pages.

basicaly i dont want to disturb First class 



//FIRST CLASS

public class BrowserFileWithStatus: FileWithStatusBase

    {

        public BrowserFileWithStatus(IBrowserFile file)

        {

            File = file ?? throw new ArgumentNullException(nameof(file));

            FileName = Path.GetFileName(File.Name);

        }

        public IBrowserFile File { get; }

    }

 public class FileWithStatusBase: IFileWithStatus

    {

        private readonly string fileName = null!;

        public string FileNameWithoutExtension { get; private init; } = null!;

        public string FileExtension { get; private init; } = null!;

        public string FileName

        {

            get => fileName;

            protected init

            {

                fileName = value;

                FileExtension = Path.GetExtension(fileName.AsSpan())[1..].ToString();

                FileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);

            }

        }

    }

 public interface IFileWithStatus

    {

        string FileNameWithoutExtension { get; }

        string FileExtension { get; }

        string FileName { get; }

    }

//SECOND CLASS-USING FOR IMAGE ONLY OPERATIONS

 public class MediaVariantUI

    {

        private BrowserFileWithStatus file;

        public MediaVariantUI(BrowserFileWithStatus file)

        {

            File = file;

            this.file = file;

            Name = file.FileName;

            ContentType = file.File.ContentType;

            FileNameWithoutExtension = file.FileNameWithoutExtension;

        }

        public BrowserFileWithStatus File { get; }

        public String Name { get; set; }

        public String FileNameWithoutExtension { get; set; }

        public String ContentType { get; set; }

    }

//MAIN UI PAGE

@page "/MediaUpload"

@using FileUpload.Models;

<EditForm Model="mediaformmodels" OnValidSubmit="CreateMediaNewFormAsync">

    <FileuploadComponent @bind-SelectedFiles="mediaformmodels.ListFileToUpload"></FileuploadComponent>

    @if (mediaformmodels.ListMediaVariantUI != null && mediaformmodels.ListMediaVariantUI.Count > 0)

            {

        <MudcardComponent MediaVariantUIList="mediaformmodels.ListMediaVariantUI"></MudcardComponent>

            }

    <MudGrid Class="mt-4 pt-1" Justify="Justify.FlexEnd">

        <MudItem>

            <MudButton Size="Size.Large"

                       Variant="Variant.Filled"

                       Color="Color.Primary"

                       StartIcon="@Icons.Material.Outlined.Save"

                       ButtonType="ButtonType.Submit">

                SUBMIT

            </MudButton>

        </MudItem>

    </MudGrid>

</EditForm>

@code {

    private MediaFormModels mediaformmodels = new();

    private async Task CreateMediaNewFormAsync()

    {

        foreach (var mediaFile in mediaformmodels.ListMediaVariantUI.Where(x => x != null))

        {

            //save each media files

        }

    }

}

//MediaFormModels class for mediaformmodels

using System.ComponentModel.DataAnnotations;

namespace FileUpload.Models

{

    public class MediaFormModels

    {

        private List<MediaVariantUI>? listMediaVariantUIValue = new();

        private List<BrowserFileWithStatus>? listFileToUpload = new();

        public IReadOnlyList<BrowserFileWithStatus>? ListFileToUpload

        {

            get

            {

                return listFileToUpload;

            }

            set

            {

                listFileToUpload = value.ToList();

                ListMediaVariantUI = value.Select(file => new MediaVariantUI(file)).ToList();

            }

        }

        public IReadOnlyList<MediaVariantUI>? ListMediaVariantUI

        {

            get { return listMediaVariantUIValue; }

            set { listMediaVariantUIValue = value.ToList(); }

        }

    }

}

//FILE UPLOAD PAGE

@using FileUpload.Models;

<h3>FileuploadComponent</h3>

<InputFile id="fileInput" OnChange="OnFilesChanged" hidden multiple />

<MudButton HtmlTag="label"

           Variant="Variant.Filled"

           Color="Color.Success"

           StartIcon="@Icons.Filled.CloudUpload"

           for="fileInput">

    Upload Image

</MudButton>

@code {

    [Parameter]

    public IReadOnlyList<BrowserFileWithStatus> SelectedFiles { get; set; } = Array.Empty<BrowserFileWithStatus>();

    [Parameter]

    public EventCallback<IReadOnlyList<BrowserFileWithStatus>> SelectedFilesChanged { get; set; }

    private async Task OnFilesChanged(InputFileChangeEventArgs eventArgs)

    {

        //i know following code is used to get image data but how can i asign to second class list when first class list triggered

        //foreach (var imageFile in e.GetMultipleFiles(maxAllowedFiles))

        //{

        //    var resizedImageFile = await imageFile.RequestImageFileAsync(format, 100, 100);

        //    var buffer = new byte[resizedImageFile.Size];

        //    await resizedImageFile.OpenReadStream().ReadAsync(buffer);

        //    var imageDataUrl = $"data:{format};base64,{Convert.ToBase64String(buffer)}";

        //}

        _ = eventArgs ?? throw new ArgumentNullException(nameof(eventArgs));

        var files = new List<BrowserFileWithStatus>(eventArgs.FileCount);

        files.AddRange(eventArgs.GetMultipleFiles(10000).Select(file => new BrowserFileWithStatus(file)));

        SelectedFiles = files;

      await SelectedFilesChanged.InvokeAsync(SelectedFiles).ConfigureAwait(false);

    }

}

For image binding i have a card component

@using FileUpload.Models;

<h3>Display selected Images</h3>

<MudPaper Width="100%" Class="darkbackground" MinHeight="350">

    <MudContainer>

        <MudGrid Spacing="@spacing" Justify="Justify.Center">

            @foreach (var item in MediaVariantUIList)

            {

                <MudItem xs="4" Style="display:flex;">

                    <MudCard Height="350px" Width="300px">

                        <MudCardMedia Image="" Height="200" />

                        <MudCardContent>

                            <input @bind="@item.FileNameWithoutExtension" @bind:event="oninput" />

                            @* <MudTextField @bind-Value="@item.FileNameWithoutExtension" @bind:event="oninput" Label="Name" Variant="Variant.Text" Margin="Margin.Dense"></MudTextField>*@

                            <MudText Class="textsilver" Typo="Typo.body2">@item.Name</MudText>

                        </MudCardContent>

                        <MudCardActions>

                            <MudIconButton Icon="@Icons.Material.Filled.Delete"  Variant="Variant.Outlined" Color="Color.Error" Size="Size.Small" />

                        </MudCardActions>

                    </MudCard>

                </MudItem>

            }

        </MudGrid>

    </MudContainer>

</MudPaper>

@code {

    public int spacing { get; set; } = 2;

    [Parameter]

    public IReadOnlyList<MediaVariantUI> MediaVariantUIList { get; set; } = Array.Empty<MediaVariantUI>();

}
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,188 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,396 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,277 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Zhi Lv - MSFT 32,016 Reputation points Microsoft Vendor
    2023-02-09T10:19:23.6033333+00:00

    Hi @RAMAN RAGAVAN

    I want to preview the image in the mud card.How can i get image url in to UI list

    Try to modify your code as below:

    Add an ImageUri property in the MediaVariantUI class, IFileWithStatus interface, and FileWithStatusBase class.

        public class BrowserFileWithStatus : FileWithStatusBase 
        { 
            public BrowserFileWithStatus(IBrowserFile file) 
            { 
                File = file ?? throw new ArgumentNullException(nameof(file)); 
                FileName = Path.GetFileName(File.Name); 
            } 
            public IBrowserFile File { get; } 
        }
        public class FileWithStatusBase : IFileWithStatus
        {
            private readonly string fileName = null!;
            public string FileNameWithoutExtension { get; private init; } = null!;
            public string FileExtension { get; private init; } = null!;
            public string ImageUri { get; set; }
            public string FileName
            {
                get => fileName;
                protected init
                {
                    fileName = value;
                    FileExtension = Path.GetExtension(fileName.AsSpan())[1..].ToString();
                    FileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
                }
            }
        }
    
        public interface IFileWithStatus
        {
            string FileNameWithoutExtension { get; }
            string FileExtension { get; }
            string FileName { get; }
            string ImageUri { get; set; }
        }
    
        //SECOND CLASS-USING FOR IMAGE ONLY OPERATIONS
        public class MediaVariantUI
        {
            private BrowserFileWithStatus file;
            public MediaVariantUI(BrowserFileWithStatus file)
            {
                File = file;
                this.file = file;
                Name = file.FileName;
                ContentType = file.File.ContentType;
                FileNameWithoutExtension = file.FileNameWithoutExtension;
                ImageUri = file.ImageUri;
            } 
            public BrowserFileWithStatus File { get; }
            public String Name { get; set; }
            public String FileNameWithoutExtension { get; set; }
            public String ContentType { get; set; }
            public string ImageUri { get; set; }
        }
    

    Then, in the FileuploadComponent component: after selecting the file, read the image file and get the based64 string to display the image.

        private async Task OnFilesChanged(InputFileChangeEventArgs eventArgs) 
        { 
            //i know following code is used to get image data but how can i asign to second class list when first class list triggered 
            //foreach (var imageFile in e.GetMultipleFiles(maxAllowedFiles)) 
            //{ 
            //    var resizedImageFile = await imageFile.RequestImageFileAsync(format, 100, 100); 
            //    var buffer = new byte[resizedImageFile.Size]; 
            //    await resizedImageFile.OpenReadStream().ReadAsync(buffer); 
            //    var imageDataUrl = $"data:{format};base64,{Convert.ToBase64String(buffer)}"; 
            //}
    
            _ = eventArgs ?? throw new ArgumentNullException(nameof(eventArgs)); 
            var files = new List<BrowserFileWithStatus>(eventArgs.FileCount); 
             
            files.AddRange(eventArgs.GetMultipleFiles(10000).Select(file => new BrowserFileWithStatus(file)).ToList()); 
    
            foreach (var imagefile in files)
            { 
                var image = await imagefile.File.RequestImageFileAsync("image/jpg", 100, 100);
                using (Stream imageStream = image.OpenReadStream(1024 * 1024 * 10))
                {
                    using MemoryStream ms = new();
                    await imageStream.CopyToAsync(ms);
                    imagefile.ImageUri = $"data:image/png;base64,{Convert.ToBase64String(ms.ToArray())}";
                }
            } 
            SelectedFiles = files; 
            await SelectedFilesChanged.InvokeAsync(SelectedFiles).ConfigureAwait(false);
    
        }
    

    After that, in the MudcardComponent component, use the following code to display image:

    <MudPaper Width="100%" Class="darkbackground" MinHeight="350"> 
        <MudContainer> 
            <MudGrid Spacing="@spacing" Justify="Justify.Center"> 
                @foreach (var item in MediaVariantUIList) 
                { 
                    <MudItem xs="4" Style="display:flex;"> 
                        <MudCard Height="350px" Width="300px">
                            <MudCardMedia Image="@item.ImageUri" Height="200" />
                            <MudCardContent>  
                                <input @bind="@item.FileNameWithoutExtension" @bind:event="oninput" /> 
                                @* <MudTextField @bind-Value="@item.FileNameWithoutExtension" @bind:event="oninput" Label="Name" Variant="Variant.Text" Margin="Margin.Dense"></MudTextField>*@
                                 <MudText Class="textsilver" Typo="Typo.body2">@item.Name</MudText>
                            
                            </MudCardContent>
                            <MudCardActions> 
                                <MudIconButton Icon="@Icons.Material.Filled.Delete" Variant="Variant.Outlined" Color="Color.Error" Size="Size.Small" /> 
                            </MudCardActions> 
                        </MudCard> 
                    </MudItem> 
                } 
            </MudGrid> 
        </MudContainer>
    
    </MudPaper>
    

    The result as below:

    User's image

    i know following code is used to get image data but how can i asign to second class list when first class list triggered

    I know you want directly to display the image via the MediaVariantUI.BrowserFileWithStatus.File, I also checked it, but it not works. So, I suggest you could use the above method.


    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,

    Dillion

    0 comments No comments

  2. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more