Konwertuj HttpPostedFileBase na bajt []


123

W mojej aplikacji MVC używam następującego kodu, aby przesłać plik.

MODEL

 public HttpPostedFileBase File { get; set; }

WIDOK

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

Wszystko działa dobrze .. Ale próbuję przekonwertować wynikowy fiel na bajt [] .Jak mogę to zrobić

KONTROLER

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

Odpowiedzi:


259

Jak mówi Darin, możesz czytać ze strumienia wejściowego - ale unikałbym polegania na wszystkich danych dostępnych za jednym razem. Jeśli używasz .NET 4, jest to proste:

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

CopyToJeśli chcesz, możesz łatwo napisać odpowiednik w .NET 3.5. Ważną częścią jest to, że czytaszHttpPostedFileBase.InputStream .

W celu efektywnego Państwo mogli sprawdzić, czy strumień wrócił już jest 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();
}

Pierwszy przykład nie działał dla mnie w .NET4 (nie wypróbowałem drugiego) - Nie działał, gdy próbowałem go z .png lub .jpg, jednak działał, gdy korzystałem z pliku .txt . Każdy pomysł dlaczego :)
— VoodooChild

2
@VoodooChild: Prawdopodobnie coś w tym, co robisz, traktuje dane jako tekst. Musiałbym zobaczyć więcej kodu, żeby wiedzieć co. Proponuję zadać kolejne pytanie, podając pełny scenariusz.
— Jon Skeet

6
ok, to zadziałało, żeby nadać kontekst - dzięki! `Image img = Image.FromStream (file.InputStream); MemoryStream ms = new MemoryStream (); img.Save (ms, ImageFormat.Jpeg); model.SiteLogo = ms.ToArray (); `
— VoodooChild

7
Odkryłem, że pozycja strumienia wejściowego znajdowała się na końcu strumienia, więc musiałem dodać wiersz model.File.InputStream.Position = 0;przed kodem Jona, aby działał
— Manish

2
@UweKeim: Cóż, tak, mamy już instrukcję using (nie dyrektywę, btw) dla inputStreami obie będą odnosić się do tego samego obiektu. Dlaczego miałbyś chcieć go pozbyć się dwa razy?
— Jon Skeet

27

Możesz to przeczytać ze strumienia wejściowego:

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

A jeśli zamierzasz bezpośrednio zapisać plik na dysku, możesz użyć tej model.File.SaveAsmetody. Poniższy wpis na blogu może okazać się przydatny.


5
Czy InputStream dla HttpPostedFileBase gwarantuje, że zwróci wszystkie dane w jednym wywołaniu Read? Jeśli to możliwe, najlepiej tego unikać.
— Jon Skeet
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.