Converti HttpPostedFileBase in byte []


123

Nella mia applicazione MVC, sto usando il seguente codice per caricare un file.

MODELLO

 public HttpPostedFileBase File { get; set; }

VISUALIZZA

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

Tutto funziona bene .. Ma sto cercando di convertire il campo dei risultati in byte []. Come posso farlo

CONTROLLER

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

Risposte:


259

Come dice Darin, puoi leggere dal flusso di input, ma eviterei di fare affidamento su tutti i dati disponibili in una volta sola. Se stai usando .NET 4 questo è semplice:

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

È abbastanza facile scrivere l'equivalente di CopyToin .NET 3.5, se lo desideri. La parte importante è che leggi HttpPostedFileBase.InputStream.

Per scopi efficienti è possibile verificare se lo stream restituito è già un 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();
}

Il primo esempio non ha funzionato per me in .NET4 (non ho provato l'altro) - Non ha funzionato quando l'ho provato con un .png o .jpg, tuttavia ha funzionato quando ho usato un file .txt . Qualche idea sul perché :)
VoodooChild

2
@VoodooChild: Presumibilmente qualcosa in quello che stai facendo è trattare i dati come testo. Avrei bisogno di vedere più codice per sapere cosa però. Ti suggerisco di fare un'altra domanda dando il tuo scenario completo.
Jon Skeet

6
ok questo ha funzionato per me, solo per dare un contesto - Grazie! `Image img = Image.FromStream (file.InputStream); MemoryStream ms = nuovo MemoryStream (); img.Save (ms, ImageFormat.Jpeg); model.SiteLogo = ms.ToArray (); `
VoodooChild

7
Stavo scoprendo che la posizione inputstream era alla fine del flusso, quindi ho dovuto aggiungere la riga model.File.InputStream.Position = 0;prima del codice di Jon per farlo funzionare
Manish

2
@ UweKeim: Ebbene sì, abbiamo già un'istruzione using (non direttiva, btw) per inputStream, ed entrambi faranno riferimento allo stesso oggetto. Perché vorresti smaltirlo due volte?
Jon Skeet

27

Puoi leggerlo dal flusso di input:

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 intendi salvare direttamente il file su disco puoi utilizzare il model.File.SaveAsmetodo. Potresti trovare utile il seguente post sul blog .


5
È garantito che InputStream per un HttpPostedFileBase restituisca tutti i suoi dati in una singola chiamata a Read? È meglio evitarlo dove possibile.
Jon Skeet
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.