jnelson
jnelson

Reputation: 61

Blazor Server Side: How to set <img> source as picture from File Share Server

Trying to set the source of an IMG container in a Blazor server-side page (internally accessible only) to a picture stored on a file share server, is giving me the error: not allowed to load local resource. Disabling the chrome security is not an option.

In the old web-forms version, the modal pop-up had the source set to a separate page that opened the image full page with the following code:

if (!string.IsNullOrEmpty(Request.QueryString["pic"]))
{
    string path = Request.QueryString["pic"];
    string file = Request.QueryString["fp"];
    byte[] Content = File.ReadAllBytes(path);


    if (file.ToUpper().Contains("PDF"))
    {
        Response.ContentType = "application/pdf";
    }
    else if (file.ToUpper().Contains("JPG") || file.ToUpper().Contains("JPEG") || file.ToUpper().Contains("PNG"))
    {
        Response.ContentType = "image/jpeg";
    }
    else if (file.ToUpper().Contains("PNG"))
    {
        Response.ContentType = "image/png";
    }
    else
    {
        Response.ContentType = "application/msword";
    }
    Response.AddHeader("content-disposition", "inline; filename=" + file);

    Response.BufferOutput = true;
    Response.OutputStream.Write(Content, 0, Content.Length);

    Response.End();
    
}

And, for the modal pop-up, the file share server path and file name were added via query string:

MPE.PopupControlID = "pic";
MPE.CancelControlID = "btnClosePic";
MPE.Show();
iFramePictures.Attributes.Add("src", "LoadImage.aspx?pic=" + attachmentPath + "&fp=" + filename);

So it was then displayed in the modal pop-up like this: example

What's the best practice way to load a file that was uploaded to a FS server as that image source? I can copy the files from a folder on that server to another destination, but can't seem to get the file to be assigned as the source for the container. Is there a way to use a memorystream as the source?

Upvotes: 0

Views: 5448

Answers (3)

jnelson
jnelson

Reputation: 61

In startup.cs:

endpoints.MapControllers();

Per mxmissle's recommendation, controller added to the project:

using Microsoft.AspNetCore.Mvc;
using System.IO;

[Route("api/[controller]")]
[ApiController]
public class Images : ControllerBase
{
    [HttpGet("[action]")]
    public IActionResult DownloadPicture(string filePath, string fileName)
    {
        string FullPath = Path.Combine(filePath, fileName);            
        var stream = new FileStream(FullPath, FileMode.Open);
        var result = new FileStreamResult(stream, "image/png");
        result.FileDownloadName = fileName;
        return result;
    }
}

And, on the page: The button click event:

<button @onclick='() => preview(A.AttachmentPath, A.AttachName)' class="oi-question-mark"></button>

And, in the button click, I just needed (Images (in the assignment of the Source variable) was the name of the controller):

void preview(string FilePath, string FileName)
{
    showModal = true;
    URL = "/api/Images/DownloadPicture?filepath=" + FilePath + "&fileName=" + FileName;
}

Which then popped up the Modal to display the image (Please forgive the in-line styling, I just needed to temporarily force the size of it) :

@if (showModal)
{
    <div class="modal" tabindex="-1" role="dialog" style="display: block; height:auto; width:1875px;">        
        <div class="modal-content" style="height: auto; width: 1875px;">
            <div class="modal-body">
                <img style="float: left; right: 5px; top: 65px; height: 865px; width: 1659px;" src="@(URL)" />
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" @onclick="Toggle" style="position:absolute; right: 0px;">Close</button>
            </div>
        </div>        
    </div>
}

Upvotes: 0

mxmissile
mxmissile

Reputation: 11672

You could use a action method in a controller:

public class ImageController : Controller
{
        public IActionResult LoadImage(string pic, string fp)
        {
            if (string.IsNullOrEmpty(pic))
                return NotFound();

            if (string.IsNullOrEmpty(fp))
                return NotFound();

            string contentType;

            if (fp.ToUpper().Contains("PDF"))
            {
                contentType = "application/pdf";
            }
            else if (fp.ToUpper().Contains("JPG") || fp.ToUpper().Contains("JPEG") || fp.ToUpper().Contains("PNG"))
            {
                contentType = "image/jpeg";
            }
            else if (fp.ToUpper().Contains("PNG"))
            {
                contentType = "image/png";
            }
            else
            {
                contentType = "application/msword";
            }

            return PhysicalFile(fp, contentType);
        }
}

Lots of ways to generate the URL, but you could just: @Url.Action("LoadImage", "Image")

Getting started with Controllers and Actions.

Upvotes: 0

Ruikai Feng
Ruikai Feng

Reputation: 11826

I tried display the local image as below:

<img src="data:image/gif;base64,@Convert.ToBase64String(File.ReadAllBytes("wwwroot/img/5.4.test.gif"))">

picture from File Share Server:

@inject HttpClient Httpclient

<img src="data:image/gif;base64,@Convert.ToBase64String(Httpclient.GetByteArrayAsync("https://avatars.githubusercontent.com/u/9141961").Result)">

in program.cs:

builder.Services.AddHttpClient();

The Result: enter image description here the offcial document related:

https://learn.microsoft.com/en-us/aspnet/core/blazor/images?view=aspnetcore-6.0

Upvotes: 0

Related Questions