DEV Community

Masui Masanori
Masui Masanori

Posted on

2 1

【ASP.NET Core】Access local files

Intro

This time, I access local files with ASP.NET Core.

  • Make static files accessable from outside
  • Get structures of directories
  • Open PDF file in web browser
  • Open movies with Razor

Environments

  • ASP.NET Core ver.3.1.302

Make static files accessible from outside

To access static files for example CSS, JavaScript, and etc, I add codes in Startup Configure.

Startup.cs

...
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            // make files what are in "wwwroot" directory accessible
            app.UseStaticFiles();

            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
...
Enter fullscreen mode Exit fullscreen mode

If I put "Book1.xlsx" into the "wwwroot" directory, I can open it by "localhost:5000/Book1.xlsx".

Use other directories

I also can make accessible other directories.

...
    app.UseStaticFiles();
    app.UseStaticFiles(new StaticFileOptions {
        FileProvider = new PhysicalFileProvider(@"C:\Users\example\Pictures\ImageSample"),
        RequestPath = "/img"
    });
...
Enter fullscreen mode Exit fullscreen mode

If I put "Book1.xlsx" into the "ImageSample" directory, I can open it by "localhost:5000/img/Book1.xlsx".

Get structures of directories

I want to get structures of directory.
So I use "PhysicalFileProvider" again.

FilePath.cs

using System.Collections.Generic;

namespace FileAccesses
{
    public struct FilePath
    {
        public string Name { get; set; }
        public string ParentPath { get; set; }
        public bool Directory { get; set; }
        public FileType FileType { get; set; }
        public List<FilePath> Children { get; set; }
    }
}
Enter fullscreen mode Exit fullscreen mode

FileType.cs

namespace FileAccesses
{
    public enum FileType
    {
        Directory = 0,
        Pdf,
        Movie,
        Others,
    }
}
Enter fullscreen mode Exit fullscreen mode

FileMapGenerator.cs

using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Extensions.FileProviders;

namespace FileAccesses
{
    public static class FileMapGenerator
    {
        public static FilePath GetPaths(string rootDirectory)
        {
            if (Directory.Exists(rootDirectory) == false)
            {
                throw new ArgumentException("Directory was not found");
            }
            using(var provider = new PhysicalFileProvider(rootDirectory))
            {
                var rootInfo = new DirectoryInfo(rootDirectory);   
                var path = new FilePath
                {
                    Name = rootInfo.Name,
                    ParentPath = "",
                    Directory = true,
                    FileType = FileType.Directory,
                    Children = new List<FilePath>(),
                };
                foreach(var content in provider.GetDirectoryContents(string.Empty))
                {
                    path.Children.Add(GetChild(provider, content, ""));
                }
                return path;   
            }
        }
        private static FilePath GetChild(PhysicalFileProvider provider,
            IFileInfo fileInfo, string parentDirectoryName)
        {
            var path = $"{parentDirectoryName}{fileInfo.Name}/";
            var newPath = new FilePath
            {
                Name = fileInfo.Name,
                ParentPath = parentDirectoryName,                
            };
            if (fileInfo.IsDirectory)
            {
                newPath.Directory = true;
                newPath.FileType = FileType.Directory;
                newPath.Children = new List<FilePath>();
                foreach(var content in provider.GetDirectoryContents(path))
                {
                    newPath.Children.Add(GetChild(provider, content, path));
                }
            }
            else
            {
                newPath.FileType = GetFileType(fileInfo);
            }
            return newPath;
        }
        private static FileType GetFileType(IFileInfo fileInfo)
        {
            var extension = Path.GetExtension(fileInfo.PhysicalPath);
            if(string.IsNullOrEmpty(extension))
            {
                return FileType.Others;
            }
            switch(extension)
            {
                case ".pdf":
                    return FileType.Pdf;
                case ".mp4":
                case ".m4a":
                    return FileType.Movie;
                default:
                    return FileType.Others;
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Open PDF file in web browser

When a request from web browser comes, I return a PDF file and open directly.

FileController.cs

using System.IO;
using FileAccesses;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;

namespace Controllers
{
    public class FileController: Controller
    {
        private readonly ILogger<FileController> _logger;
        private readonly IConfiguration _config;
        private readonly IFileAccessService _fileAccess;
        public FileController(IFileAccessService fileAccess,
            IConfiguration config,
            ILogger<FileController> logger)
        {
            _logger = logger;
            _config = config;
            _fileAccess = fileAccess;
        }
...
        [Route("/Files/Pdf")]
        public IActionResult GetPdf(string fileName, string directory = "")
        {
            using (var provider = new PhysicalFileProvider(Path.Combine(_config["BasePath"], directory)))
            {
                var stream = provider.GetFileInfo(fileName).CreateReadStream();
                // To avoid opening the file in web brower,
                // I can add a file name as the third argument.
                return File(stream, "application/pdf");
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Open movies with Razor

FileController.cs

...
    [Route("/Files/Movies")]
    public IActionResult GetMovie(string fileName, string directory = "")
    {
        _logger.LogDebug("HelloMovies");
        var fullPath = Path.Combine(_config["BasePath"], directory);
        using (var provider = new PhysicalFileProvider(fullPath))
        {
            var stream = provider.GetFileInfo(fileName).CreateReadStream();
            return File(stream, "video/mp4");
        }
    }
    [Route("/Pages/Movies")]
    public IActionResult GetMovePage(string fileName, string directory = "")
    {
        var url = $"/Files/Movies?fileName={fileName}";
        if (string.IsNullOrEmpty(directory) == false)
        {
            url += $"&directory={directory}";
        }
        ViewData["url"] = url;

        return View("./Views/MoviePage.cshtml");
    }
...
Enter fullscreen mode Exit fullscreen mode

MoviePage.cshtml

@{
    var url = ViewData["url"];
}
<video controls width="500">
    <source src="@url" type="video/mp4">
</video>
Enter fullscreen mode Exit fullscreen mode

Resources

Heroku

Deliver your unique apps, your own way.

Heroku tackles the toil — patching and upgrading, 24/7 ops and security, build systems, failovers, and more. Stay focused on building great data-driven applications.

Learn More

Top comments (3)

Collapse
 
smhasan profile image
SM Hasan

Nice

Collapse
 
servicesgideon profile image
Gideon Services

Good afternoon. I have a question how do you define your IFileAccessService?

Collapse
 
masanori_msl profile image
Masui Masanori

Hello! Thank you for reading my post :)
Originally I intended to put a function to get a file into IFileAccessService.
But at least I didn't do that in this sample, so either remove IFileAccessService or create an empty interface and class and register it in the DI container

Sentry image

Make it make sense

Only the context you need to fix your broken code with Sentry.

Start debugging →

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay