netchicken
netchicken

Reputation: 485

Images not loading using PhysicalFile or File in Razorpages

Using asp.net core 3.1 with Razorpages.

I am using PhysicalFileProvider to store files outside of the root, but cannot get them to load into an Image tag despite the path being valid.

Ideally I want to return the files to an image tag which are 90% of the files, and for those that are not then direct to the browser and then download.

I can access the physical file path but Chrome won't allow it to be seen because of security. Cutting and pasting the path into the browser returns the file successfully. So the path is working, and the file can be downloaded via cut and paste.

The full path is file:///C:/Dropbox/Enform/Files/699657ed-315c-e1d8-d4d5-39fb5550d14a/mars-programming.jpg

So I tried using PhysicalFile to pass it via a DTO to an image tag but it returned 404 with full path, the mimeType, and filename

Storage.ImagePFR = PhysicalFile(path, ext, filename);

enter image description here

Microsoft.AspNetCore.Mvc.PhysicalFileResult:1 GET https://localhost:44382/Microsoft.AspNetCore.Mvc.PhysicalFileResult 404

I thought it might be needing a relative path instead of the absolute path so used GetRelativePath from here How to get relative path from absolute path

 var relPath = GetRelativePath(@"C:/Dropbox/Enform/", @"C:/Dropbox/Enform/Files/699657ed-315c-e1d8-d4d5-39fb5550d14a/mars-programming.jpg");

but it too returned 404.

At the front end I pass it to

<img src="@Model.Storage.ImagePFR" class="card-img-top" alt="ImagePFR">

via a DTO with a Property of

public PhysicalFileResult ImagePFR { get; set; }

I tried passing with a String and Image but no difference.

I also thought to use a File

 var bytes = await System.IO.File.ReadAllBytesAsync(path);
 Storage.ImagePFR = File(bytes, ext, Path.GetFileName(path));

enter image description here

And passed it to a DTO with the property of

public FileContentResult ImagePFR { get; set; }
<img src="@Model.Storage.ImagePFR" class="card-img-top" alt="ImagePFR">

But alas, always the 404.

Edit: Thanks for the comment to add FileName as such

 <img src="@Model.Storage.ImagePFR.FileName" class="card-img-top" alt="@Model.Storage.ImagePFR.FileName">

Unfortunately all It only served to show the filename in the img tag as

<img src="c:\Dropbox\Enform\Files\699657ed-315c-e1d8-d4d5-39fb5550d14a\mars-programming.jpg" class="card-img-top" >

I eventually ended up using the following below although it would have been good to get the new tech working.

string imgType = "data:" + GetMimeTypes(Storage) + ";base64,";
Storage.Imagetest2 = string.Format(imgType + Convert.ToBase64String(System.IO.File.ReadAllBytes(path)));

Upvotes: 0

Views: 597

Answers (1)

Karan
Karan

Reputation: 12619

You need to include FileName in src tag as below.

<img src="@Model.Storage.ImagePFR.FileName" class="card-img-top" alt="ImagePFR">

What happen is when you use <img src="@Model.Storage.ImagePFR" class="card-img-top" alt="ImagePFR">, src is expecting string & @Model.Storage.ImagePFR is object. So it will return @Model.Storage.ImagePFR.ToString() which will return class's name with namespace as Microsoft.AspNetCore.Mvc.PhysicalFileResult. So when you check rendered html it will seen like <img src="Microsoft.AspNetCore.Mvc.PhysicalFileResult" class="card-img-top" alt="ImagePFR">.

Upvotes: 1

Related Questions