Reputation: 61
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:
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
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
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
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:
the offcial document related:
https://learn.microsoft.com/en-us/aspnet/core/blazor/images?view=aspnetcore-6.0
Upvotes: 0