1

I have an api that works in most functions, but not on my HttpDelete where I got 404 response.

    [Route("/[controller]")]
    [ApiController]
    public class UploadController : ControllerBase
    
..

    [HttpDelete("delete/{filename}")]
    public IActionResult Delete(string filename)
    {
        try
        {
            var filePath = Path.Combine(grundPath, ulPath, filename);
            if (System.IO.File.Exists(filePath))
            {
                System.IO.File.Delete(filePath);
                return StatusCode(200);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, ex.Message);
        }
        return StatusCode(500);
    }

My Blazor component :

..
@inject HttpClient Http
..
string url = $"delete/{filename}"
HttpResponseMessage response = await Http.DeleteAsync(url);
..

I have tried to set url = $"https://localhost:XXXX/delete..... but same result. Filename are in form "picture.png"

StatusCode: 404, ReasonPhrase: 'Not Found', Version: 1.1, Content: System.Net.Http.HttpConnectionResponse Content, Headers: { Set-Cookie: x-ms-gateway-slice=estsfd; path=/; secure; httponly DATE...

I'm a newbie on api controller so I have no clue what I missed. Don't even know where to start google...

[EDIT : Added Swagger to project]

After analysed with Swagger, I got this in swagger :

[DELETE] /delete/{filename}

Added a filename and execute, got this requested url :

https://localhost:7285/delete/_eskilssk%C3%A4rmklipp.PNG

And the file are deleted. So far so good.

Change / added code to this :

string filename = WebUtility.UrlEncode(fil.Namn);
string baseUrl = $"https://localhost:7285/delete/{filename}";
await JsRuntime.ToastrSuccess("Info : " + baseUrl);
HttpResponseMessage response = await Http.DeleteAsync(baseUrl);

My Toastr gives me :

https://localhost:7285/delete/_eskilssk%C3%A4rmklipp.PNG same as swagger...

But this in my output i Visual studio :

System.Net.Http.HttpClient.Default.LogicalHandler: Information: Start processing HTTP request DELETE https://localhost:7285/delete/_eskilsskärmklipp.PNG System.Net.Http.HttpClient.Default.ClientHandler: Information: Sending HTTP request DELETE https://localhost:7285/delete/_eskilsskärmklipp.PNG

Could it be my encoding that's wrong?

My Program.cs, maybe wrong order?

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllersWithViews()
    .AddMicrosoftIdentityUI();

builder.Services.AddRazorPages();

builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy;
    options.AddPolicy("Admin", policy => policy.RequireClaim("role", "Admin"));
});

builder.Services.AddAutoMapper(typeof(Program));

builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
}, ServiceLifetime.Transient);


builder.Services.AddServerSideBlazor()
    .AddMicrosoftIdentityConsentHandler();

builder.Services.AddScoped<>(); // Some repositories
..

builder.Services.AddScoped<DialogService>();
builder.Services.AddScoped<NotificationService>();
builder.Services.AddScoped<TooltipService>();
builder.Services.AddScoped<ContextMenuService>();

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseDeveloperExceptionPage();  // Remove when publish!!!

app.UseHttpsRedirection();

app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();
app.MapControllers();
app.MapDefaultControllerRoute();
app.MapBlazorHub();

app.MapFallbackToPage("/_Host");

app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "Blazor API V1");
});

app.Run();

2022-11-10 Problem found, when I comment out // app.UseAuthentication and app.UseAuthorization I could reach the API from my component. It's a security problem and doesn't have anything to do with this original question.
Start a new question with more correct information.

Blazor server and API in same project, 404 not found when app.UserAuth is activate

  • The action don't return 404, but the client get 404. ASP.NET Core return 404 when the url match none route . I suppose that the route segment is defined in the controller. – vernou Oct 28 '22 at 13:10
  • @vernou This : [Route("/[controller]"] on top of my controller file? (add some text above) – Tobias Gustafsson Oct 28 '22 at 13:21
  • try inverting [ApiController] [Route("[controller]")] – Francesco Oct 28 '22 at 13:29
  • Install swagger in my application now and it works when I use swagger so the error must be in my blazor component, how I call my Deletecontroller. – Tobias Gustafsson Oct 28 '22 at 13:43
  • What is the name of the controller class? `FilesController`? – vernou Oct 28 '22 at 14:55
  • @vernou : you mean this? public class UploadController : ControllerBase I use this to upload files to a secure folder. If something goes wrong when user add data to my database, I will call this Delete function to remove the uploaded file from folder again so I'm not having unlinked files. – Tobias Gustafsson Oct 28 '22 at 19:16
  • Try without special char in file's name. It will indicate if it is an encoding issue. – vernou Nov 07 '22 at 13:38
  • Add some more information, I copy my API to a new project and run that and point my baseURL to that page (runs on another port) and then it works. So maybe I missed something in my startupfiles that are needed when component and api are in same project? – Tobias Gustafsson Nov 07 '22 at 16:22
  • No, there is no such page. I will try to create a clean blazor server project and put my api-controller there and see if it works. – Tobias Gustafsson Nov 08 '22 at 09:41
  • Same code works in a fresh project so there must be something wrong in my settings / program.cs somewhere. – Tobias Gustafsson Nov 08 '22 at 09:55
  • @Henk Holterman, I think I have found the problems. My app need authentication and ofcause the API too, so I need to solve how I could give my blazor component access to my controller. – Tobias Gustafsson Nov 08 '22 at 10:56

1 Answers1

1

In ASP.NET Core, the action's route is : [controller]/[action]. In your case :

/upload/delete/{filename}

The client need to call this url like :

..
@inject HttpClient Http
..
string url = $"upload/delete/{filename}"
HttpResponseMessage response = await Http.DeleteAsync(url);
..

If you want the action's url is delete/{filename}, then you can start the action route segment by /. ASP.NET Core MVC will ignore the controller route segment when the action route segment start by / like :

[HttpDelete("/delete/{filename}")]
public IActionResult Delete(string filename)
vernou
  • 6,818
  • 5
  • 30
  • 58
  • I tried your tip, can't get it to work. Have added one uriencoder so my filstring are uri encoded so the string are the same as the one swagger use but doesn't help. Have update my question above with new information. – Tobias Gustafsson Nov 07 '22 at 12:40