Code Monkey home page Code Monkey logo

Comments (22)

fgilde avatar fgilde commented on July 18, 2024

Stream is fully available on client side?
Can you check if it works with a data url for the stream?

DataUrl.GetDataUrl(stream.ToByteArray())

That means in your case

using Nextended.Blazor.Models;
...

await dialogService.ShowFileDisplayDialog(DataUrl.GetDataUrl(stream.ToByteArray()), uploadedFile.uploaded_file_orig_file_name, mimetype, HandleContentError, ex => ex.JsRuntime = JS);

from mudblazor.extensions.

mreic avatar mreic commented on July 18, 2024

What do you mean by "fully available on client side"?
File is stored on the servers filesystem.

Testing as follows:
image

This test does not work.
If you uncomment the bytes-assignment and the second dialog call and comment out the first dialog call you can open small files. Large files get an "URI too Long"-Exception.

from mudblazor.extensions.

mreic avatar mreic commented on July 18, 2024

I just tested a little further:
If i try opening the dialog your suggested way, then opening images are working fine, but other types, like .pdf or .json files result in a immediate download which looks like this:
image
Note, that the 0 Byte files in that download list have been produced while testing.

I wrote a little function myself like this:
image

Using this allows me to open any files that are not too large for the URI.

from mudblazor.extensions.

fgilde avatar fgilde commented on July 18, 2024

Ok understand. I also fixed stream handling but that doesnt help you at all. Because for native file display (That means without custom IMudExFileDisplay implementation like Zip or Markdown handling) also a is created from stream because depending on mimetype iframe, img tag or object tags are used and they need a url

from mudblazor.extensions.

fgilde avatar fgilde commented on July 18, 2024

if youre files came from server and I would have you problems I would ensure to have a url for the file itself.
For example if you have your files in a database (or whatever) i would create a Controller to read the files.
I mean like this

using Microsoft.AspNetCore.Mvc;

[Route("api/[controller]")]
[ApiController]
public class FileController : ControllerBase
{
    private readonly IFileRepo _fileRepo;

    public FileController(IFileRepo fileRepo)
    {
        _fileRepo = fileRepo;
    }

    [HttpGet("{id}")]
    public IActionResult GetFileById(string id)
    {
        byte[] fileData = _fileRepo.GetFile(id);
        if (fileData == null || fileData.Length == 0)
        {
            return NotFound();
        }

        return File(fileData, "application/octet-stream"); // Set the appropriate MIME type if you know it.
    }
}

than you can use a url like api/file/123

Hope that helps a bit.

from mudblazor.extensions.

fgilde avatar fgilde commented on July 18, 2024

Thank you very much for sharing this bug, i fixed it and it will released in 1.7.68 you can have a look at preview package 1.7.68-prev-2309141720-main

also you can see it running here https://mudex.azurewebsites.net/handle-file-as-streams (all files here are set as stream see code)

Would you explain why you cant update MudBlazor to 6.9 ?

from mudblazor.extensions.

mreic avatar mreic commented on July 18, 2024

I'll test it tomorow..
Thank you in advance!

I cant Upgrade because of a Bug i reported in MudBlazor (MudBlazor/MudBlazor#7237).
I use exactly that combination of options in MudDataGrid and unfortunately nobody is responding at this time.. but we will see. I personally cant find a working workaround for this so i am Stuck with this Version for the moment.

from mudblazor.extensions.

fgilde avatar fgilde commented on July 18, 2024

I created a compatible package with MudBlazor 6.4.1 for you. Hope that helps.
If it does please close this issue.

1.7.68-prev-2309150848-for-mudblazor-6.4.1.

from mudblazor.extensions.

mreic avatar mreic commented on July 18, 2024

Thanks for the Package!
It helps for mostly all use-cases. Mostly, because i experienced that larger PDF-Files are not loaded.
They can be downloaded, but the preview pane keeps empty.

Any Idea on this?

Update:
It seems that i can update my project to something above 6.4.1 because somebody posted a workarround. I need to do some testing to validate this.

from mudblazor.extensions.

mreic avatar mreic commented on July 18, 2024

While further testing it seems that the file display components dont dispose properly. May be that its my code doing sth wrong, but RAM-usage increases on every dialog call and stays up even when GC takes place.

Sorry for asking so many questions ;)

from mudblazor.extensions.

fgilde avatar fgilde commented on July 18, 2024

No problem your welcome.

For question 1: Pdf and all other native display files like image etc where tag is used needs an url, and maybe your pdf is to big for a data url. I guess you need to playaround with it, or if you can provide a sample pdf I will have a look if I can do something.

For question 2: Stream is currently not disposed on component side because I dont want to close given streams because this can cause side effects. (However for MudExFileDisplayZip they are copied and maybe I need to rethink about disposing given streams )

from mudblazor.extensions.

mreic avatar mreic commented on July 18, 2024

For your first answer:
I once build a simple file preview (mostly only pdf and images) facing the nearly same problem with larger files. I found a way to do this using following function in "_host.cshtml" :

window.openFileFromStream = async (fileName, contentStreamReference, fileType) => {
    const arrayBuffer = await contentStreamReference.arrayBuffer();
    const blob = new Blob([arrayBuffer], { type: fileType });
    const url = URL.createObjectURL(blob);
    //document.querySelector("embed").src = url;

    const elem = document.getElementById("preview-element");
    if(elem != null){
        elem.src = url;
        await new Promise(resolve => setTimeout(resolve, 1000));
        URL.revokeObjectURL(url);
    }
    else{
        URL.revokeObjectURL(url);
    }

}

I personally dont know if its a nearly clean idea to get rid of the file size issue. Maybe you can check?

Second answer:
I am using this call:

string mimetype = Utilities.Utilities.GetMimeType(uploadedFile.uploaded_file_orig_file_name);

//await DialogService.ShowFileDisplayDialog($"https://localhost:1235/api/file/{uploadedFile.uploaded_file_id}", uploadedFile.uploaded_file_orig_file_name, mimetype, HandleContentError, ex => ex.JsRuntime = JS);

using (Stream stream = GetFileStream(uploadedFile))
{
    await DialogService.ShowFileDisplayDialog(stream, uploadedFile.uploaded_file_orig_file_name, mimetype, HandleContentError, ex => ex.JsRuntime = JS);
}

Seeing the code i would expect the stream to get closed and als release resources. Is there any possibilities for your component to keep data that was read from stream?

from mudblazor.extensions.

fgilde avatar fgilde commented on July 18, 2024

Your stream should get disposed, but anyway I found a bug where copied streams are staying open. I currently work on a fix for that.

For point 1 it's a good idea to use object stores uri, I think I can change the behavior to work like this

from mudblazor.extensions.

fgilde avatar fgilde commented on July 18, 2024

Can you test this package? 1.7.68-prev-2309182049-stre...

You can now set url handling to blob the MudExFileDisplay has now a Parameter for that called StreamUrlHandling
If you use a dialog you can set it like this

    private async Task OpenAsDialog()
    {
        var parameters = new DialogParameters {
            { nameof(MudExFileDisplay.StreamUrlHandling), StreamUrlHandling.BlobUrl }
        };
        await dialogService.ShowFileDisplayDialog(SampleFile.Stream, SampleFile.Name, SampleFile.ContentType, HandleContentError, null, parameters);
    }

In this example its setup to use blob uris
https://mudex.azurewebsites.net/handle-file-as-streams

from mudblazor.extensions.

mreic avatar mreic commented on July 18, 2024

Thank you for your always fast replies!
Larger PDF work now! Unfortunatly .zip-files now are broken.
image

The error is the same on calling the Dialog without the parameters.

from mudblazor.extensions.

mreic avatar mreic commented on July 18, 2024

Unfortunatelly, the info also causes crashes on all files in my test-environment
image

from mudblazor.extensions.

fgilde avatar fgilde commented on July 18, 2024

That's strange my samples with zip and other archives working well will correct stream dispose. Can you provide a sample solution with your errors? Than I can have a look

from mudblazor.extensions.

mreic avatar mreic commented on July 18, 2024

What exactly do you want to see?
I want to get it as precise as possible for you!

from mudblazor.extensions.

fgilde avatar fgilde commented on July 18, 2024

The zip and info bug reproducible should be enough. You have a server side rendered project? Maybe there is the difference. Because in my sample https://mudex.azurewebsites.net/handle-file-as-streams it works well

from mudblazor.extensions.

mreic avatar mreic commented on July 18, 2024

Yes, my project is rendered server side. I tried to open following zip:
open3A 3.8.zip

Dialog starts showing the loading spinner while the debugger prints the error from the screenshot posted earlier ("Cannot access a closed stream)

Dialog call is exacly like you suggested:

Your code:

private async Task OpenAsDialog()
    {
        var parameters = new DialogParameters {
            { nameof(MudExFileDisplay.StreamUrlHandling), StreamUrlHandling.BlobUrl }
        };
        await dialogService.ShowFileDisplayDialog(SampleFile.Stream, SampleFile.Name, SampleFile.ContentType, HandleContentError, null, parameters);
    }

My code:

private async Task OpenAsDialog(UploadedFileModel uploadedFile)
{
    //DialogOptionsEx options = new DialogOptionsEx() { JsRuntime = JS};

    //Stream stream = null;
    try
    {
        string mimetype = Utilities.Utilities.GetMimeType(uploadedFile.uploaded_file_orig_file_name);

        //await DialogService.ShowFileDisplayDialog($"https://localhost:1235/api/file/{uploadedFile.uploaded_file_id}", uploadedFile.uploaded_file_orig_file_name, mimetype, HandleContentError, ex => ex.JsRuntime = JS);

        var parameters = new DialogParameters {
            { nameof(MudExFileDisplay.StreamUrlHandling), StreamUrlHandling.BlobUrl }
        };

        using (Stream stream = GetFileStream(uploadedFile))
        {
            await DialogService.ShowFileDisplayDialog(stream, uploadedFile.uploaded_file_orig_file_name, mimetype, HandleContentError, ex => ex.JsRuntime = JS, parameters);
            //await DialogService.ShowFileDisplayDialog(stream, uploadedFile.uploaded_file_orig_file_name, mimetype, HandleContentError, ex => ex.JsRuntime = JS);
        }
    }
    catch(Exception e)
    {
        Console.Write(e.ToString());
    }

}

Hope this helps ;)

from mudblazor.extensions.

fgilde avatar fgilde commented on July 18, 2024

Sorry for Late answering today i was not at home. I see your problem. Your scope is finished to early because you are await the show of the dialog only what returns a IDialogReference from MudBlazor if you want to await the closeing to ensure dispose afterwards you need to await the result of the IDialogRefeference

       using (var stream = SampleFile.Stream) {
           var res = await dialogService.ShowFileDisplayDialog(stream, SampleFile.Name, SampleFile.ContentType, HandleContentError, null, parameters);
           await res.Result;
       }

from mudblazor.extensions.

mreic avatar mreic commented on July 18, 2024

Thanks for the Explanation!
Seems like everything is working right now.

from mudblazor.extensions.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.