c# - tutorial - aspx asp net




Como aceitar um arquivo POST (8)

Estou usando o asp.net mvc 4 webapi beta para construir um serviço de descanso. Eu preciso ser capaz de aceitar imagens / arquivos POST de aplicativos clientes. Isso é possível usando o webapi? Abaixo está como a ação que estou usando atualmente. Alguém sabe de um exemplo de como isso deve funcionar?

[HttpPost]
public string ProfileImagePost(HttpPostedFile profileImage)
{
    string[] extensions = { ".jpg", ".jpeg", ".gif", ".bmp", ".png" };
    if (!extensions.Any(x => x.Equals(Path.GetExtension(profileImage.FileName.ToLower()), StringComparison.OrdinalIgnoreCase)))
    {
        throw new HttpResponseException("Invalid file type.", HttpStatusCode.BadRequest);
    }

    // Other code goes here

    return "/path/to/image.png";
}

Aqui está uma solução rápida e suja que leva o conteúdo do arquivo carregado do corpo HTTP e o grava em um arquivo. Eu incluí um snippet HTML / JS "bare bones" para o upload do arquivo.

Método da API da Web:

[Route("api/myfileupload")]        
[HttpPost]
public string MyFileUpload()
{
    var request = HttpContext.Current.Request;
    var filePath = "C:\\temp\\" + request.Headers["filename"];
    using (var fs = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
    {
        request.InputStream.CopyTo(fs);
    }
    return "uploaded";
}

Upload de arquivo HTML:

<form>
    <input type="file" id="myfile"/>  
    <input type="button" onclick="uploadFile();" value="Upload" />
</form>
<script type="text/javascript">
    function uploadFile() {        
        var xhr = new XMLHttpRequest();                 
        var file = document.getElementById('myfile').files[0];
        xhr.open("POST", "api/myfileupload");
        xhr.setRequestHeader("filename", file.name);
        xhr.send(file);
    }
</script>

Aqui estão duas maneiras de aceitar um arquivo. Um usando no provedor de memória MultipartMemoryStreamProvider e um usando MultipartFormDataStreamProvider que salva em um disco. Note que isto é apenas para um upload de arquivo de cada vez. Você pode certamente estender isso para salvar vários arquivos. A segunda abordagem pode suportar arquivos grandes. Eu testei arquivos com mais de 200MB e funciona bem. Usando na abordagem de memória não requer que você salve no disco, mas jogará fora da exceção de memória se você exceder um certo limite.

        private async Task<Stream> ReadStream()
    {
        Stream stream = null;
        var provider = new MultipartMemoryStreamProvider();
        await Request.Content.ReadAsMultipartAsync(provider);
        foreach (var file in provider.Contents)
        {
            var buffer = await file.ReadAsByteArrayAsync();
            stream = new MemoryStream(buffer);
        }

        return stream;
    }

private async Task<Stream> ReadLargeStream()
    {
        Stream stream = null;
        string root = Path.GetTempPath();
        var provider = new MultipartFormDataStreamProvider(root);
        await Request.Content.ReadAsMultipartAsync(provider);
        foreach (var file in provider.FileData)
        {
            var path = file.LocalFileName;
            byte[] content = File.ReadAllBytes(path);
            File.Delete(path);
            stream = new MemoryStream(content);
        }

        return stream;
    }

Esta pergunta tem muitas boas respostas mesmo para o .Net Core. Eu estava usando ambos os Frameworks, os exemplos de código fornecidos funcionam bem. Então não vou repetir. No meu caso, o importante foi como usar as ações de upload de arquivos com Swagger assim:

Aqui está minha recapitulação:

ASP .Net WebAPI 2

  • Para fazer o upload do arquivo use: MultipartFormDataStreamProvider veja as respostas aqui
  • Como usá-lo com o Swagger

.NET Core


Estou surpreso que muitos de vocês parecem querer salvar arquivos no servidor. Solução para manter tudo na memória é a seguinte:

[HttpPost, Route("api/upload")]
public async Task<IHttpActionResult> Upload()
{
    if (!Request.Content.IsMimeMultipartContent())
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 

    var provider = new MultipartMemoryStreamProvider();
    await Request.Content.ReadAsMultipartAsync(provider);
    foreach (var file in provider.Contents)
    {
        var filename = file.Headers.ContentDisposition.FileName.Trim('\"');
        var buffer = await file.ReadAsByteArrayAsync();
        //Do whatever you want with filename and its binary data.
    }

    return Ok();
}

Eu usei a resposta de Mike Wasson antes de atualizar todas as NuGets no meu projeto webapi mvc4. Depois disso, tive que reescrever a ação de upload do arquivo:

    public Task<HttpResponseMessage> Upload(int id)
    {
        HttpRequestMessage request = this.Request;
        if (!request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.UnsupportedMediaType));
        }

        string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/uploads");
        var provider = new MultipartFormDataStreamProvider(root);

        var task = request.Content.ReadAsMultipartAsync(provider).
            ContinueWith<HttpResponseMessage>(o =>
            {
                FileInfo finfo = new FileInfo(provider.FileData.First().LocalFileName);

                string guid = Guid.NewGuid().ToString();

                File.Move(finfo.FullName, Path.Combine(root, guid + "_" + provider.FileData.First().Headers.ContentDisposition.FileName.Replace("\"", "")));

                return new HttpResponseMessage()
                {
                    Content = new StringContent("File uploaded.")
                };
            }
        );
        return task;
    }

Aparentemente, BodyPartFileNames não está mais disponível no MultipartFormDataStreamProvider.


O caminho do ASP.NET Core está agora here :

[HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
    long size = files.Sum(f => f.Length);

    // full path to file in temp location
    var filePath = Path.GetTempFileName();

    foreach (var formFile in files)
    {
        if (formFile.Length > 0)
        {
            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await formFile.CopyToAsync(stream);
            }
        }
    }

    // process uploaded files
    // Don't rely on or trust the FileName property without validation.

    return Ok(new { count = files.Count, size, filePath});
}

Veja o código abaixo, adaptado deste artigo , que demonstra o código de exemplo mais simples que encontrei. Inclui uploads de arquivos e de memória (mais rápidos).

public HttpResponseMessage Post()
{
    var httpRequest = HttpContext.Current.Request;
    if (httpRequest.Files.Count < 1)
    {
        return Request.CreateResponse(HttpStatusCode.BadRequest);
    }

    foreach(string file in httpRequest.Files)
    {
        var postedFile = httpRequest.Files[file];
        var filePath = HttpContext.Current.Server.MapPath("~/" + postedFile.FileName);
        postedFile.SaveAs(filePath);
        // NOTE: To store in memory use postedFile.InputStream
    }

    return Request.CreateResponse(HttpStatusCode.Created);
}

veja http://www.asp.net/web-api/overview/formats-and-model-binding/html-forms-and-multipart-mime#multipartmime , embora eu ache que o artigo faz parecer um pouco mais complicado do que é realmente.

Basicamente,

public Task<HttpResponseMessage> PostFile() 
{ 
    HttpRequestMessage request = this.Request; 
    if (!request.Content.IsMimeMultipartContent()) 
    { 
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); 
    } 

    string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/uploads"); 
    var provider = new MultipartFormDataStreamProvider(root); 

    var task = request.Content.ReadAsMultipartAsync(provider). 
        ContinueWith<HttpResponseMessage>(o => 
    { 

        string file1 = provider.BodyPartFileNames.First().Value;
        // this is the file name on the server where the file was saved 

        return new HttpResponseMessage() 
        { 
            Content = new StringContent("File uploaded.") 
        }; 
    } 
    ); 
    return task; 
} 




asp.net-mvc-4