MVC Img to Byte[] - asp.net-mvc

My Model
partial class Company
{
... More Properties
public HttpPostedFileBase FilePicture { get; set; }
public byte[] Picture { get; set; }
}
My Controller
[HttpPost]
public ActionResult Edit(int id, Models.Company model)
{
if(model.FilePicture != null)
{
using(Stream inputStream = model.FilePicture.InputStream)
{
MemoryStream memoryStream = inputStream as MemoryStream;
if(memoryStream == null)
{
memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
}
model.Picture = memoryStream.ToArray();
}
}
//EditDefault does the persisting
return this.EditDefault(id, model);
}
My View
#using (Html.BeginForm("Edit", currentController, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
//Clicks on the Picture and the Upload butten are forwarded to the file input tag
//readUrl sets the image as sone as the file changes
<input id="filePicture" type="file" name="filePicture" onchange="readURL(this);">
<button type="button" id="pictureUploadBtnPicture" onclick="$('#filePicture').click();"> Upload</button>
//ClearImg clears the img tag and resets the file input tag
<button type="button" id="pictureDeleteBtnPicture" onclick="clearimg(this);"> Delete</button>
...if Picture not null
...{
<img id="PicturePicture" src="data:image/png;base64,#System.Convert.ToBase64String(#Model.Picture.ToArray())">
<input type="hidden" value="#System.Convert.ToBase64String(#Model.Picture.ToArray())" name="Picture"> **added**
...}
...else ... Render empty Picture and set it per javascript
<input type="submit" value="Safe" class="btn btn-primary">
}
I have a Form which contains some properties like name, city,... and a byte[] which contains the data for a picture. The upload, show and delete are working. My problem now is that when I change something and I safe the site again, the Picture Property is null in the model, that I get in the Post Action. I guess there is something not working with the mapping.
Just to be clear I want the img mapped to the byte[].
Thx in advance for any help :)
Update:
Thx to Matt Tabor ;)
Added a hidden input field and now I get it in the controller.
Updated the View in case somebody needs it.

<img id="Picture" name="Picture" src="data:image/png;base64,#System.Convert.ToBase64String(#Model.Picture.ToArray())">
this property is not an input, when you submit this to the server it wont sumbit the image.
you would have to use something like a hidden input storing the byte array.
try adding this under your image tag
#Html.HiddenFor(m=>m.Picture)

Related

Upload File From View to Controller in .net Core

I'm trying to create a .net core project with file upload.
In the model I have a class name "Movie" with 2 properties: Image - of type byte[] and Picture - of type IFormFile.
In the view I added a form with the input:
<input asp-for="Picture" type="file" id="image_upload" />
And in my controller I have a function like that:
public IActionResult NewMovie(Movie movie){...
In the movie object that is passed the property Image and Picture are always NULL.
I tried changing the asp-for from Image to Picture, to change the function to be of type Task, to add IFormFile to the function calling and nothing helped.
I never been able to get the file's data. I need it to be of type byte[] but I'll take anything to help me.
Thank you all in advance.
You dont need to store the image in a byte array your model only needs an IFormFile like this:
Model:
[Required(ErrorMessage = "The {0} field is required")]
[Display(Name = "Image")]
[DataType(DataType.Upload)]
public IFormFile Image { get; set; }
Controller:
if (model.Image == null)
return View(model);
string uploadsFolder = Path.Combine(webHostEnvironment.WebRootPath,"Your upload path");
string ImagePath = Guid.NewGuid().ToString() + "_" + model.Image.FileName;
string filePath = Path.Combine(uploadsFolder, ImagePath);
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
await model.Image.CopyToAsync(fs);
}
Add this to your form tag: enctype="multipart/form-data".
Its essential for the type="file" input to be submitted.
View:
<form enctype="multipart/form-data" Other attributes...>
<div class="custom-file">
<input asp-for="Model.Image" type="file" class="custom-file-input fileUpload" />
<label class="custom-file-label fileLabel">Choose file</label>
</div>
<input type="submit" value="Submit" />
</form>
And finally you save the ImagePath only in your db entity.

MVC File upload Where to put code

OK, so I am trying to make the move to MVC.
I have a Model, view and Controller made, but now I want to change the create functionality of the app.
I am working with uploads and I have this system generated code in my contoller.
Function Create(<Bind(Include:="Id,Course,Category,SubCategory,FileName,FileType,UploadedBy,DateUploaded")> ByVal acAsset As acAsset) As ActionResult
If ModelState.IsValid Then
db.Assets.Add(acAsset)
db.SaveChanges()
Return RedirectToAction("Index")
End If
Return View(acAsset)
End Function
Now I want to change this so that it will
Check for the existence of a folder for Course, Category and Sub category. If this folder is not there it must be created.
Upload the file select by a file selection box.
Post the files' name to the db.
The code is not necessarily the issue, I am jut not sure where I should put in the controller?
I have read this article but is not dealing with the DB post.
Thank you in advance.
You just add your code in controller that you want to hit on button click
Your Razor View Code
#using (Html.BeginForm("Upload", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" name="Submit" id="Submit" value="Upload" />
}
C# Code
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
file.SaveAs(path);
}
return RedirectToAction("UploadDocument");
}
}
In your View
<input type="file" name="file">
In your Controller
public actionresult(HttpPostedFileBase file)
{
string filename = Path.GetFileName(file.FileName);
string contentType = file.ContentType;
using (Stream fs = file.InputStream)
{
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((Int32)fs.Length);
}
}
//Data Context Code here
tableName.File= bytes;
db.add(tableName);
db.SaveChanges();
}

How to check FileUploader have file in MVC4 asp.net

I am creating an application in mvc4. In edit mode i want user to edit his/her details,
user have option to change his profile image by selecting from fileuploader. But if user do not select file in uploader the previous file location will be sent.
I am storing image path in table same as other details.
So, only one Stored procedure is created.
I am only 1 day old in mvc.Started working on mvc directly, without studying by seniors order.
So pls help
It is a good practice to use strongly typed models. You should create a separater ViewModel for your User:
Models/UserEditViewModel
public int Id { get; set; }
public string Name { get; set; }
// Other properties
public HttpPostedFileBase Photo { get; set; }
Controller:
[HttpGet]
public ActionResult Edit(int id)
{
// Get user from database
var user = db.Users.Find(id);
// Map user to UserEditViewModel
var userVM = new UserEditViewModel
{
Id = user.Id;
Name = user.Name;
// Other mappings
}
return View(userVM);
}
[HttpPost]
public ViewResult Edit(UserEditViewModel model)
{
if (ModelState.IsValid)
{
var existingUser = db.Users.Find(model.Id);
if (model.Photo != null && model.Photo.ContentLength > 0)
{
// Update database and copy image to server
}
}
}
View:
#model YourProject.Models.UserEditViewModel
#using (Html.BeginForm("Edit", "YourController", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
// Form stuff
#Html.HiddenFor(m => m.Id)
#Html.EditorFor(m => m.Name)
#Html.EditorFor(m => m.Photo) // Creates <input type="file" name="Photo" />
<input type="submit" value="Save" />
}
The following code is on the assumption that you save the file's name in the db table and save the file on the app server.
The code will be as follows:
Model:
public string Photo {get;set;}
View :
<input type='file' id='file'/>
#Html.HiddenFor(m=>m.Photo)
JS :
// if there is a photo update by user, change the Photo hidden element value
//get the final name of the photo saved in server
$("#Photo").val(newname);
Then simply post your form.
In case, the user doesn't change its photo, then the previous value will remain in the hidden element and updated to the db. Hence, nothing will actually change in the photo column.
I strongly recommend this tutorial for MVC beginners.

How to get file from HDD to Bitmap object [ASP MVC 3]?

I'm new to ASP MVC and I've been trying to upload a bitmap file from hard drive to a C# Bitmap object, which I would later assign to my Model.
The view (cshtml file) looks like this:
<form action = "DisplayAddedPicture" method=post>
<input type=file name="Picture" id = "Picture"/>
<input type=submit value="Send!" />
</form>
And the DisplayAddedPicture method from controller:
[HttpPost]
public ActionResult DisplayAddedPicture()
{
HttpPostedFileBase File = Request.Files["Picture"];
if (File == null) throw new Exception("NullArgument :( ");
// file stream to byte[]
MemoryStream target = new MemoryStream();
File.InputStream.CopyTo(target);
byte[] TempByteArray = target.ToArray();
// byte[] to Bitmap
ImageConverter imageConverter = new ImageConverter();
Image TempImage = (Image)imageConverter.ConvertFrom(TempByteArray);
Bitmap FinalBitmap = new Bitmap(TempImage);
// (...)
}
It turns out that every time all I get is an Exception, as the HttpPostedFileBase object is always null. Is there any flow in my logic (apart from all of those conversions which come afterwards, I know they're messy) or is there any other way to solve this?
Try this
In your View,
#using (Html.BeginForm("DisplayAddedPicture", "YourControllerName",
FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type=file name="Picture" id = "Picture"/>
<input type=submit value="Send!" />
}
And the Action method
[HttpPost]
public ActionResult DisplayAddedPicture(HttpPostedFileBase Picture)
{
if (Picture!= null && Picture.ContentLength > 0)
{
//Do some thing with the Picture object
//try to save the file here now.
//After saving follow the PRG pattter (do a redirect)
//return RedirectToAction("Uploaded");
}
return View();
}
Try adding the following to your form tag: enctype="multipart/form-data"
<form method="post" action="DisplayAddedPicture" enctype="multipart/form-data">
<input type=file name="Picture" id = "Picture"/>
<input type=submit value="Send!" />
</form>

MVC 3 fileupload dialog

I think those tags pretty much says what i'm asking..
I have been struggling with file upload. What I need to achieve is open a dialog for file upload and save it to database, so nothing too fancy.
Basic file upload is more than easy to make. Just form with correct encrypt and input type file. But when I insert my form to dialog something goes wrong and there is nothing in Post. I tried to add test parameters like filename and it worked fine. But the actual file is missing in post.
here's some code:
Form:
#using (Html.BeginForm("Edit", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" })){
<label for="Name">Filename: </label>
<input type="text" name="name" id="name"/>
<input type="file" name="file" id="file" />
<input type="submit"/>
}
Controller:
public ActionResult Edit(Attachment model)
{
var strLen = Convert.ToInt32(model.file.InputStream.Length);
var strArr = new byte[strLen];
model.file.InputStream.Read(strArr, 0, strLen);
return View();
}
Edit:
Model:
public class Attachment
{
public string Name { get; set; }
public HttpPostedFileBase file{ get; set; }
}
This form is inside the dialog.
Try this,
public ActionResult Edit(HttpPostedFileBase file)
{
////
return View();
}

Resources