Reputation: 7443
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.
Upvotes: 6
Views: 19229
Reputation: 7443
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.
Upvotes: 2
Reputation: 582
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
Upvotes: 1
Reputation: 11734
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.
Upvotes: 2
Reputation: 152521
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);
}
Upvotes: 8