Chuyển đổi HTTPPostedFileBase thành byte []


123

Trong ứng dụng MVC của tôi, tôi đang sử dụng mã sau để tải lên một tệp.

MÔ HÌNH

 public HttpPostedFileBase File { get; set; }

LƯỢT XEM

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

Mọi thứ đều hoạt động tốt .. Nhưng tôi đang cố gắng chuyển đổi kết quả fiel thành byte []. Làm thế nào tôi có thể làm điều này

KIỂM SOÁT

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

Câu trả lời:


259

Như Darin nói, bạn có thể đọc từ luồng đầu vào - nhưng tôi sẽ tránh dựa vào tất cả dữ liệu có sẵn trong một lần. Nếu bạn đang sử dụng .NET 4 thì điều này thật đơn giản:

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

Thật dễ dàng để viết tương đương với CopyTo.NET 3.5 nếu bạn muốn. Phần quan trọng là bạn đọc từ HttpPostedFileBase.InputStream.

Đối với mục đích hiệu quả, bạn có thể kiểm tra xem luồng được trả về đã là 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();
}

Ví dụ đầu tiên không hoạt động với tôi trong .NET4 (không thử cái khác) - Nó không hoạt động khi tôi thử nó với .png hoặc .jpg, tuy nhiên nó đã hoạt động khi tôi sử dụng tệp .txt . Bất cứ ý tưởng tại sao :)
VoodooChild

2
@VoodooChild: Có lẽ một cái gì đó trong những gì bạn đang làm là coi dữ liệu là văn bản. Tôi cần xem thêm mã để biết mặc dù. Tôi đề nghị bạn hỏi một câu hỏi khác đưa ra kịch bản đầy đủ của bạn.
Jon Skeet

6
ok điều này làm việc cho tôi, chỉ để đưa ra một số bối cảnh - Cảm ơn! `Image img = Image.FromStream (file.InputStream); MemoryStream ms = new MemoryStream (); img.Save (ms, ImageFormat.Jpeg); model.SiteLogo = ms.ToArray (); `
VoodooChild

7
Tôi đã thấy rằng vị trí đầu vào nằm ở cuối luồng, vì vậy tôi phải thêm dòng model.File.InputStream.Position = 0;trước mã của Jon để làm cho nó hoạt động
Manish

2
@UweKeim: Vâng, chúng tôi đã có một tuyên bố sử dụng (không phải chỉ thị, btw) cho inputStreamvà cả hai sẽ đề cập đến cùng một đối tượng. Tại sao bạn muốn vứt bỏ nó hai lần?
Jon Skeet

27

Bạn có thể đọc nó từ luồng đầu vào:

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

Và nếu bạn có ý định trực tiếp lưu tệp vào đĩa, bạn có thể sử dụng model.File.SaveAsphương thức này. Bạn có thể tìm thấy bài viết blog sau đây hữu ích.


5
InputStream cho một HTTPPostedFileBase có được đảm bảo trả lại tất cả dữ liệu của nó trong một cuộc gọi đến Đọc không? Tốt nhất là tránh điều đó khi có thể.
Jon Skeet
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.