Problem
How to access directory and file information in ASP.NET Core, ensuring restricted access to file system.
Solution
Starting from an empty project, amend the Startup
class:
public void ConfigureServices(
IServiceCollection services)
{
services.AddSingleton<IFileProvider>(
new PhysicalFileProvider(Directory.GetCurrentDirectory()));
}
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env)
{
app.UseHelloFileProvider();
}
Create a middle to read contents of directory:
public class HelloFileProviderMiddleware
{
private readonly RequestDelegate next;
private readonly IFileProvider fileProvider;
public HelloFileProviderMiddleware(
RequestDelegate next,
IFileProvider fileProvider)
{
this.next = next;
this.fileProvider = fileProvider;
}
public async Task Invoke(HttpContext context)
{
var output = new StringBuilder("");
IDirectoryContents dir = this.fileProvider.GetDirectoryContents("");
foreach (IFileInfo item in dir)
{
output.AppendLine(item.Name);
}
await context.Response.WriteAsync(output.ToString());
}
}
You could also read a particular file’s contents:
public class HelloFileProviderMiddleware
{
private readonly RequestDelegate next;
private readonly IFileProvider fileProvider;
public HelloFileProviderMiddleware(
RequestDelegate next,
IFileProvider fileProvider)
{
this.next = next;
this.fileProvider = fileProvider;
}
public async Task Invoke(HttpContext context)
{
IFileInfo file = this.fileProvider.GetFileInfo("Startup.cs");
using (var stream = file.CreateReadStream())
using (var reader = new StreamReader(stream))
{
var output = await reader.ReadToEndAsync();
await context.Response.WriteAsync(output.ToString());
}
}
}
Discussion
ASP.NET Core provides an encapsulation of System.IO.File
type in order to limit the access to file system via PhysicalFileProvider
type, which is an implementation of IFileProvider
.
IFileProvider
can be configured as a service (in Startup
) and then injected as dependency in middleware, controllers, etc. This keeps the configuration of file access (e.g., the directory to access) in one place, at the application start-up.
IFileProvider
has two important methods:
GetDirectoryContents
: Returns IDirectoryContents
. This can be used to iterate over files/folders in a directory.
GetFileInfo
: returns IFileInfo
. This can be used to read the file via its CreateReadStream
.