แปลง HttpPostedFileBase เป็นไบต์ []


123

ในแอปพลิเคชัน MVC ของฉันฉันใช้รหัสต่อไปนี้เพื่ออัปโหลดไฟล์

MODEL

 public HttpPostedFileBase File { get; set; }

ดู

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

ทุกอย่างทำงานได้ดี .. แต่ฉันกำลังพยายามแปลงผลลัพธ์ fiel เป็น byte [] ฉันจะทำสิ่งนี้ได้อย่างไร

CONTROLLER

 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: สันนิษฐานว่ามีบางอย่างในสิ่งที่คุณทำคือการปฏิบัติต่อข้อมูลเป็นข้อความ ฉันต้องการดูรหัสเพิ่มเติมเพื่อให้ทราบว่าเป็นอย่างไร ฉันขอแนะนำให้คุณถามคำถามอื่นเพื่ออธิบายสถานการณ์ทั้งหมดของคุณ
Jon Skeet

6
ตกลงสิ่งนี้ใช้ได้กับฉันเพียงเพื่อให้บริบท - ขอบคุณ! `รูปภาพ img = Image.FromStream (file.InputStream); MemoryStream ms = MemoryStream ใหม่ (); img บันทึก (ms, ImageFormat.Jpeg); model.SiteLogo = ms ToArray (); `
VoodooChild

7
ฉันพบว่าตำแหน่งอินพุตสตรีมอยู่ที่ส่วนท้ายของสตรีมดังนั้นฉันจึงต้องเพิ่มบรรทัดmodel.File.InputStream.Position = 0;ก่อนโค้ดของจอนเพื่อให้มันใช้งานได้
Manish

2
@UweKeim: ใช่เรามีคำสั่งใช้แล้ว (ไม่ใช่คำสั่ง btw) สำหรับinputStreamและทั้งสองจะอ้างถึงวัตถุเดียวกัน ทำไมคุณถึงต้องการกำจัดทิ้งสองครั้ง?
Jon Skeet

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 รับประกันว่าจะส่งคืนข้อมูลทั้งหมดในการเรียกอ่านครั้งเดียวหรือไม่ ควรหลีกเลี่ยงสิ่งนั้นหากทำได้
Jon Skeet
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.