How to Save Files to Separate Server by Extension

Asked

Viewed 763 times

3

I have a WEB API who receives a file via POST follows the code of Controller:

public async Task<HttpResponseMessage> Post()
  {
        // Ver se POST é MultiPart? 
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }
        // Preparar CustomMultipartFormDataStreamProvider para carga de dados
        // (veja mais abaixo)

        string fileSaveLocation = HttpContext.Current.Server.MapPath("~/Arquivos/Uploads");
        CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(fileSaveLocation);
        List<string> files = new List<string>();
        try
        {
            // Ler conteúdo da requisição para CustomMultipartFormDataStreamProvider. 
            await Request.Content.ReadAsMultipartAsync(provider);

            foreach (MultipartFileData file in provider.FileData)
            {
                files.Add(Path.GetFileName(file.LocalFileName));
            }
            // OK se tudo deu certo.
            return Request.CreateResponse(HttpStatusCode.OK, files);
        }
        catch (System.Exception e)
        {
            return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
        }
    }

My method: CustomMultipartFormDataStreamProvider

public class CustomMultipartFormDataStreamProvider :     MultipartFormDataStreamProvider
{
    public CustomMultipartFormDataStreamProvider(string path) 
        : base(path) { }
    public override string GetLocalFileName(HttpContentHeaders headers)
    {
        return headers.ContentDisposition.FileName;
    }
}

I’m saving the files in a folder Files/Uploads however, I need to save the files that are received in separate folders, for example Word in a folder called Word etc....

The way I’m doing it now is a little bureaucratic but it works. I have a class Utilities that upon receiving the file it makes a copy of the file to the folder it should be in and deletes the file inside the folder Files/Uploads.

There is a way to simplify this, which through the controller Post i identify the file extension and save it to the respective folder on the server?

  • Is the folder name exactly equal to the extension? The folder is already created or should be created if it does not exist?

  • Until then I created some folders with the most known extensions, and had thought to leave the ones that are not so well known in a folder "Others". However it is interesting this approach, to create the folder if it does not exist.

  • Renan, you forgot the first question. The folder name will be the same as the extension?

  • True, yes the same name.

  • That one CustomMultipartFormDataStreamProvider is something you have created or some external lib?

  • I implicit it, edited the question and inserted it. To save the file name. I saw in a reply here in the PT-SO http://answall.com/a/153255/61561

  • How’s your utility class code?

Show 2 more comments

1 answer

4


I won’t go into detail about the MultipartFormDataStreamProvider. It could be something a little extensive, so I’ll just show you how to modify your code to do what you want.

First, as you want to create a folder with the extension name if it does not exist, you will need to create the method for this. To simplify, you can use the method below:

private String CriarDiretorioSeNaoExistir(string path)
    {
        var returnPath = HttpContext.Current.Server.MapPath(path);

        if (!Directory.Exists(returnPath))
            Directory.CreateDirectory(HttpContext.Current.Server.MapPath(path));

        return returnPath;
    }

It simply checks if the directory exists. If it does not exist it will create. And as a return it returns the complete path, ie your fileSaveLocation.

After that, we will just move the saved file to the new directory, this way:

File.Move(file.LocalFileName,
           Path.Combine(CriarDiretorioSeNaoExistir(Path.Combine("~/Arquivos/Uploads", file.LocalFileName.Split('.').LastOrDefault())),
           file.LocalFileName.Split('\\').LastOrDefault()));

This way we are getting the file saved with the file.LocalFileName and moving to the new folder (which comes after the comma). And in the same method we are already checking and creating the directory if it does not exist (feel free to separate if you think necessary).

Your complete code will look like this:

public async Task<HttpResponseMessage> Post()
{
    // Ver se POST é MultiPart? 
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }
    // Preparar CustomMultipartFormDataStreamProvider para carga de dados
    // (veja mais abaixo)

    string fileSaveLocation = HttpContext.Current.Server.MapPath("~/Arquivos/Uploads");
    CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(fileSaveLocation);
    List<string> files = new List<string>();
    try
    {
        // Ler conteúdo da requisição para CustomMultipartFormDataStreamProvider. 
        await Request.Content.ReadAsMultipartAsync(provider);

        foreach (MultipartFileData file in provider.FileData)
        {
            files.Add(Path.GetFileName(file.LocalFileName));
              File.Move(file.LocalFileName,
                    Path.Combine(CriarDiretorioSeNaoExistir(Path.Combine("~/Arquivos/Uploads", file.LocalFileName.Split('.').LastOrDefault())),
                    file.LocalFileName.Split('\\').LastOrDefault()));
        }
        // OK se tudo deu certo.
        return Request.CreateResponse(HttpStatusCode.OK, files);
    }
    catch (System.Exception e)
    {
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
    }
}


private String CriarDiretorioSeNaoExistir(string path)
{
    var returnPath = HttpContext.Current.Server.MapPath(path);

    if (!Directory.Exists(returnPath))
        Directory.CreateDirectory(HttpContext.Current.Server.MapPath(path));

    return returnPath;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.