Konvertieren Sie HttpPostedFileBase in Byte []

123

In meiner MVC-Anwendung verwende ich den folgenden Code, um eine Datei hochzuladen.

MODELL

 public HttpPostedFileBase File { get; set; }

AUSSICHT

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

Alles funktioniert gut. Aber ich versuche, das Ergebnisfeld in Byte [] umzuwandeln. Wie kann ich das tun?

REGLER

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

Antworten:

259

Wie Darin sagt, können Sie aus dem Eingabestream lesen - aber ich würde es vermeiden, mich darauf zu verlassen, dass alle Daten auf einmal verfügbar sind. Wenn Sie .NET 4 verwenden, ist dies einfach:

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

Es ist einfach genug, das Äquivalent von CopyToin .NET 3.5 zu schreiben, wenn Sie möchten. Der wichtige Teil ist, dass Sie aus lesen HttpPostedFileBase.InputStream.

Für die Zwecke der effizienten Sie könnten überprüfen , ob die zurückgegebene Stream ist bereits ein 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
quelle
Das erste Beispiel hat in .NET4 bei mir nicht funktioniert (das andere nicht ausprobiert) - Es hat nicht funktioniert, als ich es mit einer .png- oder .jpg-Datei ausprobiert habe, aber es hat funktioniert, als ich eine .txt-Datei verwendet habe . Irgendeine Idee warum :)
VoodooChild
2
@VoodooChild: Vermutlich etwas in dem, was Sie tun, um die Daten als Text zu behandeln. Ich müsste mehr Code sehen, um zu wissen, was. Ich schlage vor, Sie stellen eine andere Frage mit Ihrem vollständigen Szenario.
Jon Skeet
6
ok das hat bei mir funktioniert, nur um einen Kontext zu geben - Danke! `Image img = Image.FromStream (file.InputStream); MemoryStream ms = neuer MemoryStream (); img.Save (ms, ImageFormat.Jpeg); model.SiteLogo = ms.ToArray (); `
VoodooChild
7
Ich stellte fest, dass sich die Inputstream-Position am Ende des Streams befand, also musste ich die Zeile model.File.InputStream.Position = 0;vor Jons Code hinzufügen , damit es funktioniert
Manish
2
@UweKeim: Nun ja, wir haben bereits eine using-Anweisung (nicht Direktive, übrigens) für inputStream, und beide beziehen sich auf dasselbe Objekt. Warum sollten Sie es zweimal entsorgen wollen?
Jon Skeet
27

Sie können es aus dem Eingabestream lesen:

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
    }
    ...
}

Wenn Sie die Datei direkt auf der Festplatte speichern möchten, können Sie die model.File.SaveAsMethode verwenden. Der folgende Blog-Beitrag ist möglicherweise hilfreich.

Darin Dimitrov
quelle
5
Wird vom InputStream für eine HttpPostedFileBase garantiert , dass alle Daten in einem einzigen Aufruf von Read zurückgegeben werden? Es ist am besten, dies nach Möglichkeit zu vermeiden.
Jon Skeet