Sujeet Raman

Sujeet Raman

  • 862
  • 927
  • 353.9k

Unable to bind the selected image file in Blazor file upload

Feb 3 2023 10:14 AM

I am learning blazor and c# fundas with a simple app.This app will allow you to
browse all kind of files including images.As all kind files we can browse, i need a seperate class
for 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; }
    }

 

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

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

   
}