Перетворити HttpPostedFileBase в байт []


123

У своїй програмі MVC я використовую наступний код для завантаження файлу.

МОДЕЛЬ

 public HttpPostedFileBase File { get; set; }

ПОГЛЯД

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

Все працює добре .. Але я намагаюся перетворити результат fiel у байт []. Як я можу це зробити

КОНТРОЛЕР

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

Відповіді:


259

Як каже Дарін, ви можете читати з вхідного потоку, але я б уникав покладатися на всі дані, доступні за один раз. Якщо ви використовуєте .NET 4, це просто:

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

Досить просто написати еквівалент CopyToв .NET 3.5, якщо хочете. Важлива частина, яку ви читаєте HttpPostedFileBase.InputStream.

Для ефективних цілей ви можете перевірити, чи повернений потік вже є 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();
}

Перший приклад для мене не працював у .NET4 (не намагався інший) - він не працював, коли я спробував це з .png або .jpg, проте він працював, коли я використовував файл .txt . Будь-яка ідея чому :)
VoodooChild

2
@VoodooChild: Імовірно, щось у тому, що ви робите, - це обробляти дані як текст. Мені потрібно переглянути більше коду, щоб знати, що все-таки. Я пропоную вам задати ще одне питання, даючи повний сценарій.
Джон Скіт

6
ОК, це працювало для мене, просто щоб дати деякий контекст - Дякую! `Image img = Image.FromStream (file.InputStream); MemoryStream ms = новий MemoryStream (); img.Save (мс, ImageFormat.Jpeg); model.SiteLogo = ms.ToArray (); `
VoodooChild

7
Я з'ясував, що позиція вхідного потоку знаходиться в кінці потоку, тому мені довелося додати рядок model.File.InputStream.Position = 0;перед кодом Джона, щоб він працював
Маніш

2
@UweKeim: Ну так, у нас уже є оператор використання (не директива, btw) для inputStream, і обидва будуть посилатися на один і той же об’єкт. Чому ви хотіли б утилізувати його двічі?
Джон Скіт

27

Ви можете прочитати його з вхідного потоку:

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

І якщо ви маєте намір безпосередньо зберегти файл на диску, ви можете скористатися model.File.SaveAsметодом. Наступне повідомлення в блозі може бути корисним.


5
Чи гарантується, що InputStream для HttpPostedFileBase поверне всі свої дані в одному дзвінку на Read? Краще уникати цього, де це можливо.
Джон Скіт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.