0

I need to upload files from a client to a server. But I found a problem, I can not filter the files. I need to discard files that do not have a suitable extension . If the file does not have the right extension then I will not load it to the server.

I tried to filter, but I don't have any idea how to write this. Can anyone help me with this part?

public enum FileExtension 
    {
    Unknown = 0,
    Doc = 1,
    Rtf = 2,
    Html = 3
}

public static class FileExtensionExtensions {
    public static string GetExtension(this FileExtension ext) {
        switch (ext) {
        case FileExtension.Doc:
            return ".doc";
        case FileExtension.Html:
            return ".html";
        case FileExtension.Rtf:
            return ".rtf";
        default:
            throw new ArgumentException();
        }
    }

    public static FileExtension GetFileExtension(string ext) {
        if (string.IsNullOrWhiteSpace(ext)) throw new ArgumentException("message", nameof(ext));
        ext = ext.Trim('.').ToLower();

        switch (ext) {
        case ".doc":
            return FileExtension.Doc;
        case ".html":
            return FileExtension.Html;
        case ".rtf":
            return FileExtension.Rtf;
        default:
            throw new ArgumentException();
        }
    }
}

[Route("api")][ApiController]
public class UploadDownloadController:
ControllerBase {
    private IHostingEnvironment _hostingEnvironment;

    public UploadDownloadController(IHostingEnvironment environment) {

        _hostingEnvironment = environment;
    }

    [HttpPost][Route("upload")]
    public async Task < IActionResult > Upload(IFormFile file) {
        string fileExtension = Path.GetExtension(file.FileName).Trim('.');

        if (file.Length > 0) {
            string dir = Folder.GetAllPath(Path.Combine(Folder.GetAllPath, fileExtension));
            string filePath = Path.Combine(dir, file.FileName);
            using(var fileStream = new FileStream(filePath, FileMode.Create)) {
                await file.CopyToAsync(fileStream);
            }
        }
        return Ok();
    }

    [HttpGet][Route("download")]
    public async Task < IActionResult > Download([FromQuery] string file) {
        string fileExtension = Path.GetExtension(file).Trim('.');
        string dir = Folder.GetAllPath(Path.Combine(Folder.GetAllPath, fileExtension));
        string filePath = Path.Combine(dir, file);
        if (!System.IO.File.Exists(filePath)) return NotFound();

        var memory = new MemoryStream();
        using(var stream = new FileStream(filePath, FileMode.Open)) {
            await stream.CopyToAsync(memory);
        }
        memory.Position = 0;
        return File(memory, GetContentType(filePath), file);
    }

    [HttpGet][Route("files")]
    public IActionResult Files() {
        var result = new List < string > ();

        if (Directory.Exists(Folder.GetAllPath("txt"))) {
            var files = Directory.GetFiles(Folder.GetAllPath("txt")).Select(fn = >Path.GetFileName(fn));
            result.AddRange(files);
        }
        return Ok(result);
    }

    private string GetContentType(string path) {
        var provider = new FileExtensionContentTypeProvider();
        string contentType;
        if (!provider.TryGetContentType(path, out contentType)) {
            contentType = "application/octet-stream";
        }
        return contentType;
    }
}

}

Alex
  • 1
  • 2
  • 1
    https://stackoverflow.com/questions/3152157/find-a-file-with-a-certain-extension-in-folder/3152180 does this help? – Barış Akkurt Aug 08 '19 at 06:20
  • Possible duplicate of [Find a file with a certain extension in folder](https://stackoverflow.com/questions/3152157/find-a-file-with-a-certain-extension-in-folder) – Tim Rutter Aug 08 '19 at 06:24
  • @BarışAkkurt no, I need to upload only those files to the server that are listed in public enum FileExtension { Unknown = 0, Doc = 1, Rtf = 2, Html = 3 } – Alex Aug 08 '19 at 06:28

1 Answers1

0

Your first problem here is that the code you are showing is server side code. That means you can only detect the file type after the file (IFormFile) has been uploaded. I assume you want to stop the file selection and file upload before the files are uploaded. You will have to do this on the client side with JavaScript or a client side framework like Angular.

A pointer: When defining the file input in your Html DOM you can specify which extensions to allow. E.g. .txt, .csv You can extend this to mime types as well. E.g. image/jpg, image/gif. Note that this is not foolproof and can only be described as best effort. Client side validation will still be needed.

<input type="file" accept=".txt, .csv" />
<input type="file" accept="image/jpg, image/gif">
<input type="file" accept=".txt, .csv, image/jpg, image/gif">