Converter HttpPostedFileBase em byte []

123

No meu aplicativo MVC, estou usando o código a seguir para fazer upload de um arquivo.

MODELO

 public HttpPostedFileBase File { get; set; }

VISÃO

@Html.TextBoxFor(m => m.File, new { type = "file" })

Tudo funcionando bem .. Mas estou tentando converter o resultado fiel em byte [] .Como posso fazer isso

CONTROLADOR

 public ActionResult ManagePhotos(ManagePhotos model)
    {
        if (ModelState.IsValid)
        {
            byte[] image = model.File; //Its not working .How can convert this to byte array
        }
     }
Ponteiro nulo
fonte

Respostas:

259

Como Darin diz, você pode ler a partir do fluxo de entrada - mas eu evitaria depender de todos os dados disponíveis de uma só vez. Se você estiver usando o .NET 4, isso é simples:

MemoryStream target = new MemoryStream();
model.File.InputStream.CopyTo(target);
byte[] data = target.ToArray();

É fácil escrever o equivalente CopyTono .NET 3.5, se você quiser. A parte importante é que você lê HttpPostedFileBase.InputStream.

Para propósitos eficientes, você pode verificar se o fluxo retornado já é um MemoryStream:

byte[] data;
using (Stream inputStream = model.File.InputStream)
{
    MemoryStream memoryStream = inputStream as MemoryStream;
    if (memoryStream == null)
    {
        memoryStream = new MemoryStream();
        inputStream.CopyTo(memoryStream);
    }
    data = memoryStream.ToArray();
}
Jon Skeet
fonte
O primeiro exemplo não funcionou para mim no .NET4 (não tentei o outro) - Não funcionou quando tentei com um .png ou .jpg, mas funcionou quando usei um arquivo .txt . Qualquer idéia de por que :)
VoodooChild
2
@VoodooChild: Presumivelmente, algo no que você está fazendo é tratar os dados como texto. Eu precisaria ver mais código para saber o que. Eu sugiro que você faça outra pergunta, fornecendo seu cenário completo.
precisa
6
ok, isso funcionou para mim, apenas para dar algum contexto - Obrigado! `Image img = Image.FromStream (file.InputStream); MemoryStream ms = novo MemoryStream (); img.Save (ms, ImageFormat.Jpeg); model.SiteLogo = ms.ToArray (); `
VoodooChild
7
Eu estava achando que a posição inputstream estava no fim do fluxo, então eu tive que adicionar a linha model.File.InputStream.Position = 0;antes do código de Jon para fazer o trabalho
Manish
2
@UweKeim: Bem, sim, já temos uma declaração de uso (não diretiva, btw) para inputStream, e ambos se referem ao mesmo objeto. Por que você quer descartá-lo duas vezes?
precisa
27

Você pode lê-lo no fluxo de entrada:

public ActionResult ManagePhotos(ManagePhotos model)
{
    if (ModelState.IsValid)
    {
        byte[] image = new byte[model.File.ContentLength];
        model.File.InputStream.Read(image, 0, image.Length); 

        // TODO: Do something with the byte array here
    }
    ...
}

E se você deseja salvar diretamente o arquivo no disco, você pode usar o model.File.SaveAsmétodo Você pode achar útil a seguinte postagem no blog .

Darin Dimitrov
fonte
5
É garantido que o InputStream para um HttpPostedFileBase retorne todos os seus dados em uma única chamada para Read? É melhor evitar isso sempre que possível.
quer