How to use controllers in a Blazor web app? My route is not being found.
local host page can't be found
I have AddControllers
and MapControllers
in my program.cs
.
I want to be able to add a simple route to this controller so I can test how to download files, but I am unable to route to this controller when I type into the url.
I am not sure what I am missing or how to get the controller to be called. I have done the map and add controllers which has not brought anything.
using Microsoft.AspNetCore.Mvc;
using System.IO.Compression;
namespace SecureFileShare.Controllers
{
public class HomeController : ControllerBase
{
[ApiController]
[Route("api/[controller]")]
public class FilesController : ControllerBase
{
private readonly IWebHostEnvironment _hostEnvironment;
public FilesController(IWebHostEnvironment hostEnvironment)
{
_hostEnvironment = hostEnvironment;
}
[HttpGet]
[Route("download-zip")]
public IActionResult DownloadFiles()
{
try
{
var folderPath = Path.Combine(_hostEnvironment.ContentRootPath, "FilesToDownload");
// Ensure the folder exists
if (!Directory.Exists(folderPath))
return NotFound("Folder not found.");
// Get a list of files in the folder
var files = Directory.GetFiles(folderPath);
if (files.Length == 0)
return NotFound("No files found to download.");
// Create a temporary memory stream to hold the zip archive
using (var memoryStream = new MemoryStream())
{
// Create a new zip archive
using (var zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
foreach (var file in files)
{
var fileInfo = new FileInfo(file);
// Create a new entry in the zip archive for each file
var entry = zipArchive.CreateEntry(fileInfo.Name);
// Write the file contents into the entry
using (var entryStream = entry.Open())
using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read))
{
fileStream.CopyTo(entryStream);
}
}
}
memoryStream.Seek(0, SeekOrigin.Begin);
// Return the zip file as a byte array
return File(memoryStream.ToArray(), "application/zip", "files.zip");
}
}
catch (Exception ex)
{
return StatusCode(500, $"An error occurred: {ex.Message}");
}
}
}
}
}
using SecureFileShare.Client.Pages;
using SecureFileShare.Components;
using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Components.Server.Circuits;
using Microsoft.Extensions.DependencyInjection.Extensions;
using SecureFileShare.Services;
var builder = WebApplication.CreateBuilder(args);
// For windows authentication
// ---------------------
// First add nuget package Microsoft.AspNetCore.Authentication.Negotiat
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = options.DefaultPolicy;
});
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
// Inject IHttpContextAccessor
builder.Services.AddHttpContextAccessor();
// Injects
builder.Services.AddScoped<UserService>();
builder.Services.TryAddEnumerable(
ServiceDescriptor.Scoped<CircuitHandler, UserCircuitHandler>());
builder.Services.AddControllers(); ///I ADDED CONTROLLER HERE
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// 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.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
///
app.UseAuthentication();
app.UseAuthorization();
///
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(SecureFileShare.Client._Imports).Assembly);
app.MapControllers(); ///I MAPPED CONTROLLER HERE
app.Run();
I am not sure what I am missing or how to get the controller to be called. I have done the map and add controllers which has not brought anything.
Based on your shared code snippet and description ,the issue lies in the nesting of your FilesController
class. Because, you currently have FilesController
nested within HomeController
. This is incorrect because controllers should be separate classes.
I have reproduced the issue accordingly as you can see below:
In order to fix this issue, your fileController should have its own class instead of being nested within HomeController class.
Just create another controller class with FilesController
itself. You can do as following:
[ApiController]
[Route("api/[controller]")]
public class FilesController : ControllerBase
{
private readonly IWebHostEnvironment _hostEnvironment;
public FilesController(IWebHostEnvironment hostEnvironment)
{
_hostEnvironment = hostEnvironment;
}
[HttpGet]
[Route("download-zip")]
public IActionResult DownloadFiles()
{
}
}
Output:
The request has been hit the download-zip
action as expected.
Note: Please refer to this official document. Also routing in web API.