DEV Community

Masui Masanori
Masui Masanori

Posted on

【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

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