angularfile-uploadasp.net-core-webapi.net-8.0angular19

Getting HTTP status: 401 when displaying an image in Angular app from Web API backend


I am getting a status code: 401 in the console when trying to fetch and display an image from my ASP.NET Core 8.0 Web API in my Angular 19 application. Please read the case scenario below, very closely and minutely.

I am uploading an image from my Angular application and it gets copied to a folder called RecipeImages under Resources in my Web API project structure, ie. the path is

WebAPI project --> Resources --> RecipeImages (images are copied here)

Simultaneously, I am saving the path in the database. The images are being copied to the desired path absolutely fine. The respective paths are also being saved in the database just fine.

An example of a saved path in the database is:

Resources\RecipeImages\Nigella_GarlicButterMushroom_638706726811613226.jpg

Note that the path is with backslashes. I followed the approach used in this tutorial to do the task:
https://code-maze.com/upload-files-dot-net-core-angular/

Now I am trying to display this image in a component. Upon ngOnInit, I have written code to make a call to the backend service and get all the data from that database table. Fetching them and preparing the path to bind to the src attribute of the image control.

component.html:

<img [src]="createImagePath(selectedRecipeDetails.imagePath)" alt="" class="circular_recipe" style="height:410px; width: 410px;" />

component.ts:

createImagePath(path: any) {
  return `https://localhost:7164/${path}`;
}

When I am inspecting the blank/vacant image element on my page, the complete path that I am getting on the src attribute is as:

src="https://localhost:7164/Resources\RecipeImages\Nigella_GarlicButterMushroom_638706726811613226.jpg"

7164 is the port number on which my Web API backend is running. As you can see, there is a whole lot of mess with forward and backslashes.

I also made code changes in Program.cs so that my Web API backend can serve static files - like this:

Program.cs:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers()
    .AddNewtonsoftJson(opts =>
    {
        opts.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    });
builder.Services.Configure<FormOptions>(o =>
{
    o.ValueLengthLimit = int.MaxValue;
    o.MultipartBodyLengthLimit = int.MaxValue;
    o.MemoryBufferThreshold = int.MaxValue;
});

builder.Services.AddSwaggerExplorer()
    .InjectDbContext(builder.Configuration)
    .AddAppConfig(builder.Configuration)
    .AddIdentityHandlersAndStores()
    .AddIdentityAuth(builder.Configuration);

builder.Services.AddApplicationServices();

var app = builder.Build();

app.ConfigureCORS(builder.Configuration)
    .ConfigureSwaggerExplorer()
    .AddIdentityAuthMiddlewares();

app.UseDefaultFiles();
app.UseStaticFiles();

app.UseStaticFiles(new StaticFileOptions()
{
    FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"Resources")),
    RequestPath = new PathString("/Resources")
});

app.MapControllers();

app.Run();

Basically, I did everything in toe-toe, with the tutorial. Still, I do not understand why I am unable to render the image in my component. I downloaded and ran the finished project from that tutorial to make sure that it was workable. It is!

But why there is an anomaly in my application? Goes without saying if I manually change all the backslashes in the saved path in the database to forward slashes, it still doesn't serve anything! My image control remains blank.

Can you folks spot anything? Any small detail that I may be overlooking? Or is there more code to be added/edited in the frontend and backend?

Please help sort this out!


Solution

  • As mentioned in the comment, Middleware order affects how the request is processed.

    From the link, the Static File Middleware (UseStaticFiles) should be placed before the CORS middleware (UseCors) and authentication and authorization middlewares.

    var app = builder.Build();
    
    app.UseDefaultFiles();
    app.UseStaticFiles();
    
    app.UseStaticFiles(new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"Resources")),
        RequestPath = new PathString("/Resources")
    });
    
    app.ConfigureCORS(builder.Configuration)
       .ConfigureSwaggerExplorer()
       .AddIdentityAuthMiddlewares();
    
    app.MapControllers();
    
    app.Run();