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.