0

I am making a very simple minimal api image uploader, and i cannot for the life of me figure out why the image will not show post upload. It launches properly, allows me to upload the image, saves the image in the correct directory, but will not display the image properly. I'll attach the code, and a screenshot below.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Define a class to hold image information


// Set up static file serving
app.UseStaticFiles();

// Set up the route for the upload form
app.MapGet("/", async context =>
{
    context.Response.ContentType = "text/html";

    await context.Response.WriteAsync(@"
        <html>
            <head>
                <title>Image Uploader</title>
            </head>
            <body>
                <h1>Image Uploader</h1>
                <form method=""post"" enctype=""multipart/form-data"" action=""/upload"">
                    <label for=""title"">Title of Image:</label><br/>
                    <input type=""text"" id=""title"" name=""title"" required/><br/><br/>
                    <label for=""image"">Select Image (JPEG, PNG, GIF):</label><br/>
                    <input type=""file"" id=""image"" name=""image"" accept=""image/jpeg, image/png, image/gif"" required/><br/><br/>
                    <input type=""submit"" value=""Upload""/>
                </form>
            </body>
        </html>
    ");
});

// Set up the route for handling the image upload
app.MapPost("/upload", async context =>
{
    var title = context.Request.Form["title"];
    var imageFile = context.Request.Form.Files.GetFile("image");

    // Validate inputs
    if (string.IsNullOrWhiteSpace(title) || imageFile == null)
    {
        context.Response.Redirect("/error"); // Redirect to an error page if validation fails
        return;
    }

    // Generate a unique ID for the uploaded image
    var imageId = Guid.NewGuid().ToString();

    // Save the uploaded image file to a directory
    var imageDirectory = Path.Combine(Directory.GetCurrentDirectory(), @"C:\Users\curti\OneDrive\Desktop\ImageUploader\Images");
    Directory.CreateDirectory(imageDirectory);
    var imagePath = Path.Combine(imageDirectory, imageId + Path.GetExtension(imageFile.FileName));
    using (var stream = File.Create(imagePath))
    {
        await imageFile.CopyToAsync(stream);
    }

    // Create an ImageInfo object with the uploaded image details
    var imageInfo = new ImageInfo
    {
        Id = imageId,
        Title = title,
        FileName = imageFile.FileName
    };

    // Save the image info to a JSON file
    var jsonFilePath = Path.Combine(Directory.GetCurrentDirectory(), "images.json");
    var existingImages = File.Exists(jsonFilePath) ? JsonSerializer.Deserialize<List<ImageInfo>>(await File.ReadAllTextAsync(jsonFilePath)) : new List<ImageInfo>();
    existingImages.Add(imageInfo);
    await File.WriteAllTextAsync(jsonFilePath, JsonSerializer.Serialize(existingImages));

    // Redirect to the page showing the uploaded image
    context.Response.Redirect($"/picture/{imageId}");
});

// Set up the route for displaying the image details
app.MapGet("/picture/{id}", async context =>
{
    var imageId = context.Request.RouteValues["id"]?.ToString();

    // Load the image info from the JSON file
    var jsonFilePath = Path.Combine(Directory.GetCurrentDirectory(), "images.json");
    var existingImages = File.Exists(jsonFilePath) ? JsonSerializer.Deserialize<List<ImageInfo>>(await File.ReadAllTextAsync(jsonFilePath)) : new List<ImageInfo>();
    var imageInfo = existingImages.FirstOrDefault(i => i.Id == imageId);

    if (imageInfo == null)
    {
        context.Response.Redirect("/error"); // Redirect to an error page if image not found
        return;
    }

    context.Response.ContentType = "text/html";

    var imageUrl = $"{context.Request.Scheme}://{context.Request.Host}/images/{imageInfo.Id}{Path.GetExtension(imageInfo.FileName)}";

    await context.Response.WriteAsync($@"
    <html>
        <head>
            <title>Image Details</title>
        </head>
        <body>
            <h1>Image Details</h1>
            <h2>Title: {imageInfo.Title}</h2>
            <img src=""{imageUrl}"" alt=""{imageInfo.Title}""/>
        </body>
    </html>
    ");
});

app.Run();

public class ImageInfo
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string FileName { get; set; }
}

Screenshot

I tried hardcoding the file directory as well but that gave the same result.

1 Answers1

0

You may have to map the images physical directory (where your uploaded image(s) are stored) to the web servers virtual "/images/" path, for example:

// Map "images" to an external folder ...

app.UseStaticFiles(new StaticFileOptions()
{
    FileProvider = new PhysicalFileProvider(
            System.IO.Path.GetFullPath( imageDirectory )),
    RequestPath = new PathString("/images"),
    DefaultContentType = "application/octet-stream"
});

Other helpful guides may be found at:

bdcoder
  • 3,280
  • 8
  • 35
  • 55
  • The problem now seems to be that when i inspect it, it is showing the wrong image link after uploaded. @bdcoder – Curtis Antisdel Jul 03 '23 at 00:41
  • Can you give an example of "wrong image link"? – bdcoder Jul 03 '23 at 01:06
  • Yeah. When i inspect and hover over the above image where the image file is supposed to be, It gives me the image https directory on where its pulling from or the image link. Usually, you could paste it into google or whatever and it would show you the image, however, it is taking me to a 404 error page suggesting that there is no such image. @bdcoder – Curtis Antisdel Jul 03 '23 at 01:26
  • Make sure the mapping of the "/images" virtual directory is correct. That is, can you verify the physical directory where the uploaded image exists and make sure the "/images" virtual path is mapped to that directory? In other words, first verify that the uploaded image is being saved. Second, note the directory it is saved in. Third, make sure the "/images" virtual path is mapped to that directory. Hope that makes sense. – bdcoder Jul 03 '23 at 01:40