Reputation: 295
This is the first time I'm working with file uploads in ASP.NET MVC, and I've been able to upload an image, resize it, save it to the server, rename the src-string so the src to image reflect the products name (for example: "ProductImages/Original/FIFA14.jpg"). The image src is also stored in the database which I use to Display the images in the view with an Url.Action().
For my edit post, I want the user to be able to change the product information as usual. And everytime a user submits the form, the image that has been uploaded before will be overwritten with the new imagefile which has been uploaded.
When I enter the Edit Product Get View, the file input says "no file has been chosen". I want it to show the image file that the user uploaded before when he created the product from his local computer.
Is there really a way to that, and how?
Here's my File input in Edit View:
<div class="form-group">
@Html.LabelFor(model => model.ProductImageViewModel.ImageUpload, new { @class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="imageUpload" id="imageUpload" />
@Html.ValidationMessageFor(model => model.ProductImageViewModel.ImageUpload)
</div>
</div>
The Controller method for Edit Get:
// GET: /Product/Edit/5
public ActionResult Edit(Guid id)
{
Product product = _productRepository.GetById(id);
var productViewModel = new ProductViewModel
{
Id = product.Id,
Name = product.Name,
Description1 = product.Description1,
Description2 = product.Description2,
Description3 = product.Description3,
Status = product.Status,
Image = product.Image,
Weight = product.Weight,
Price = product.Price,
ReleaseDate = product.ReleaseDate,
Category = product.Category,
Categories = GetCategoryDropDownListForEdit(product),
ProductStatuses = GetStatusDropDownListForEdit(product),
};
return View(productViewModel);
}
This is how I upload the Image in the Create Method:
// POST: /Product/Create
[HttpPost]
public ActionResult Create(ProductViewModel model, HttpPostedFileBase imageUpload)
{
if (UploadedFileIsValidImage(imageUpload))
{
byte[] productPicture = new byte[imageUpload.ContentLength];
imageUpload.InputStream.Read(productPicture, 0, imageUpload.ContentLength);
WebImage img = new WebImage(imageUpload.InputStream);
img.Resize(200, 200);
var fileName = imageUpload.FileName;
string imageName = model.Name;
string extension = Path.GetExtension(fileName);
var productImageFileName = imageName + extension;
img.FileName = productImageFileName;
var filePathOriginal = Server.MapPath("~/ProductImages/Originals");
var filePathThumbNail = Server.MapPath("~/ProductImages/ThumbNails");
string savedImageFileName = Path.Combine(filePathOriginal, productImageFileName);
img.Save(savedImageFileName);
model.ProductImageViewModel.ImageSrc = savedImageFileName;
model.Image = savedImageFileName;
try
{
var guid = new Guid(model.SelectedCategory);
_manager.AddProduct(
model.Name, model.Description1, model.Description2, model.Description3, Convert.ToDecimal(model.Price),
Convert.ToDateTime(model.ReleaseDate),
Convert.ToDouble(model.Weight), model.ProductImageViewModel.ImageSrc, guid);
_categoryRepository.Save();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
else
{
model.Categories = CategoryDropDownListForCreate();
return View(model);
}
}
So how can I get the input to show the current uploaded file for this product in the file input?
Upvotes: 3
Views: 17926
Reputation: 1
First i Saved the URl of my image in DB, then I had to go around the problem and solved it with this
// Add this to your controller to check if the file is coming empty, If yes then I copy my previous Url to the new edited object
else if (file== null)
{
Product thisProduct = db.Products.Where(p => p.Id == product.Id).FirstOrDefault();
product.Url = thisProduct.Url;
}
if (ModelState.IsValid)
{
// had to use AddOrUpdate instead of Modified
db.Set<Product>().AddOrUpdate(product);
//db.Entry(product).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
Upvotes: 0
Reputation: 994
Try this way (not solution but a way around to work),
In Edit View, show a link of uploaded image and an image upload control side by side.
If user want to see/preview the uploaded image, can use link of image.
For new image which intimately replace the old image. You can check this is controller Edit
method. If HttpPostedFileBase imageUpload
is not null then update, otherwise just save the model into database.
As already mentioned by other users, for security reason you cannot assign the path to input control.
Upvotes: 0
Reputation: 5545
You cannot do so as it is a security issue. If you try to set it through javascript with the following piece of code
<script type="text/javascript">
document.forms["form1"].elements["uploadImage"].value = "C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";
</script>
If you can check your browser console, it outputs error message saying that
SecurityError: The operation is insecure.
Upvotes: 1
Reputation: 2493
When the type of the input is "file" you can't set the value of it. Usually you will add a link to download the current uploaded file in the edit view.
Upvotes: 0