简体   繁体   中英

Cannot convert HttpPostedFileBase to Byte[]

I have a controller that takes in a HttpPostedFileBase (a .jpg or .png, etc.).

public ActionResult SaveImage(HttpPostedFileBase ImageData)
{
  //code
}

ImageData becomes a System.Web.HttpPostedFileWrapper object with these properties:

ContentLength: 71945
ContentType: "image/png"
FileName: "foo.png"
InputStream: {System.Web.HttpInputStream}

I don't have any problems taking the ImageData and converting it to an Image, and then converting the Image to a byte[] and then to a base64 string - but I tried converting it directly into a byte[] with the following code:

byte[] imgData;

using (Stream inputStream = ImageData.InputStream)
{
    MemoryStream memoryStream = inputStream as MemoryStream;
    if (memoryStream == null)
    {
        memoryStream = new MemoryStream();
        inputStream.CopyTo(memoryStream);
    }

    imgData = memoryStream.ToArray();
}

memoryStream is always empty by the time imgData = memoryStream.ToArray(); is invoked, so imgData ends up being null as well.

I'm having a hard time understanding why I cannot read this InputStream into a MemoryStream. The InputStream seems seems fine, with the exception of the readTimeout and writeTimeout properties throwing timeouts are not supported on this stream . What am I doing wrong, and how come I can't convert ImageData into a byte[]?

Just in case, this is my AJAX call. Could it be an issue with the contentType or processData options being set to false?

$.ajax({
    url: 'SaveImage',
    data: formData,
    type: "POST",
    contentType: false,
    processData: false,
    beforeSend: function () {
        $("#loadingScreenModal").modal('toggle');
    },
    success: function (data) {
        // etc.
    }
});

UPDATE: I resolved the issue by converting the HttpPostedFileBase to an Image , and then converting the Image to a byte[] , but I'm still interested in figuring out why I have to perform this intermediate step.

Image i = Image.FromStream(ImageData.InputStream, true, true);
byte[] imgData = imageToByteArray(thumb);

public byte[] imageToByteArray(Image imageIn)
{
    MemoryStream ms = new MemoryStream();
    imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
    return ms.ToArray();
}

UPDATE #2: I think it probably stands to reason that the problem with my code is the code within the if (memoryStream == null) block never being invoked.

You can use the BinaryReader class to read a string into a byte array:

byte[] imgData;

using (var reader = new BinaryReader(ImageData.InputStream))
{
    imgData = reader.ReadBytes(ImageData.ContentLength);
}

I have similar code, wherein I read the stream directly into a byte[] like so:

var streamLength = ImageData.InputStream.Length;
var imageBytes = new byte[streamLength];
ImageData.InputStream.Read(imageBytes, 0, imageBytes.Length);

I then store imageBytes into the database as a varbinary(MAX) . Seems to work fine.

The answer ended up being the memoryStream == null check, as JoeEnos suggested. MemoryStream is instantiated on the line directly above this check - so it should never be null - and should be checked with if (memoryStream.Length == 0) instead.

Model Code

public class AdminDetailsModel
{
    public byte[] AdminImage { get; set; }
 }

View Code

@using (Html.BeginForm("Create", "AdminDetails", FormMethod.Post, new { enctype = "multipart/form-data" }))
{   
    <div class="form-group">
        @Html.LabelFor(model => model.AdminImage, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <input type="file" name="ImageData" id="ImageData" />                              
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>

Code like this in Your Controller

public ActionResult Create(AdminDetailsModel viewmodel)
{
    if (ModelState.IsValid)
    {
    HttpPostedFileBase file = Request.Files["ImageData"];
    viewmodel.Image = ConvertToByte(file);
    db.YourDbContextSet.Add(viewmodel);
    db.SaveChanges();
    }
}

public byte[] ConvertToByte(HttpPostedFileBase file)
    {
        byte[] imageByte = null;
        BinaryReader rdr = new BinaryReader(file.InputStream);
        imageByte = rdr.ReadBytes((int)file.ContentLength);
        return imageByte;
    }

Hope this will help

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM