I'm trying to make a website using asp.net mvc 4 where I can store data in MSSQL db & store uploaded image files in local storage. So far data is storing successfully but whenever I select multiple images to upload, it only uploads the first selected image only. Here are my codes,
Controller
[HttpPost]
public ActionResult FlatManager(FlatMgt FlatTable, HttpPostedFileBase[] files)
{
if (Session["username"] != null)
{
if (ModelState.IsValid)
{
var AddFlat = FlatTable.Flats;
db.FlatInfoes.Add(AddFlat);
db.SaveChanges();
foreach (HttpPostedFileBase file in files)
{
if (file != null && file.ContentLength > 0)
{
int imageCount = 0;
string picName = FlatTable.Flats.flatno.ToString() + "-" + imageCount;
string picExt = Path.GetExtension(file.FileName);
if (picExt == ".jpg" || picExt == ".gif" || picExt == ".jpeg")
{
picExt = ".png";
}
string path = System.IO.Path.Combine(Server.MapPath("~/Images/"), picName + picExt);
file.SaveAs(path);
imageCount++;
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
byte[] array = ms.GetBuffer();
}
}
else
{
TempData["add_fail"] = "Error! Wrong File Type(s)! Please Try Again.";
return RedirectToAction("FlatManager");
}
}
TempData["add_success"] = "Information Added Successfully!";
return RedirectToAction("FlatManager");
}
else
{
TempData["add_fail"] = "Error! Please Provide Valid Information.";
return RedirectToAction("FlatManager");
}
}
else
{
return RedirectToAction("Login");
}
}
View
#using (Html.BeginForm("FlatManager", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
<label for="file">Upload Image:</label>
<input type="file" multiple="multiple" name="files" id="file" style="width: 100%;" /><br />
<input type="submit" value="Add" />
}
I can't find any error in my codes. How can I solve this problem? Will be really helpful if someone helps. Thanks.
Related
Here is my controller code to save my uploaded image in my application folder ("~/Content/Files") and to store the path in the database table named "imageupload".
my objective is to display all the images stored in the folder ("~/Content/Files") using the path in my database table.
[HttpPost]
public ActionResult Index(prop prop)
{
var db = new db_DotnetEntities();
HttpPostedFileBase file = Request.Files[0];
if (ModelState.IsValid)
{
var tbl = new imageupload();
if (file == null)
{
ModelState.AddModelError("File", "Please Upload file");
}
else if (file.ContentLength > 0)
{
int MaxContentLength = 1024 * 1024 * 3;
string[] allowedFileExtensions = { ".jpeg", ".png", ".pdf", "gif" };
if (!allowedFileExtensions.Contains(file.FileName.Substring(file.FileName.LastIndexOf('.'))))
{
ModelState.AddModelError("File", "Please File of type" + string.Join(",", allowedFileExtensions));
}
else if (file.ContentLength > MaxContentLength)
{
ModelState.AddModelError("File", "Your file is too large, maximum allowed size is: " + MaxContentLength + " MB");
}
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Content/Files"), fileName);
tbl.imageurl = fileName;
db.imageuploads.Add(tbl);
db.SaveChanges();
file.SaveAs(path);
ModelState.AddModelError("File", "Image Sucessfully Uploaded");
}
}
return View();
}
Here is My Model
public class prop
{
public string fileimg { get; set; }
}
Here is My view
#model imageMVC.Models.prop
#using (Html.BeginForm("index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary()
#Html.TextBoxFor(x=>x.fileimg,new{#type="File"})
<input type="submit" id="submit"/>
}
I am using ADO Data Entity Model.
kindly tell me how to write code to display all images stored in ("~/Content/Files").
Thanks in Advance.
Here is my Model.I have Added a list Property to takes list of images in the folder ("~/Content/Files")
public class Prop
{
public string Fileimg { get; set; }
public IEnumerable<string> Images { get; set; }
}
Here is my ActionResult of controller to Display List of images in folder ("~/Content/Files")
public ActionResult List(Prop obj)
{
obj.Images=Directory.EnumerateFiles(Server.MapPath("~/Content/Files/"))
.Select(fn => "~/Content/Files/" + Path.GetFileName(fn));
var objfile = new DirectoryInfo(Server.MapPath("~/Content/Files/"));
var file = objfile.GetFiles("*.*");
return View(obj);
}
Here is My View to loop all the images and display all in the view
#model imageMVC.Models.Prop
<table style="border: solid">
<tr>
<th>IMAGES</th>
</tr>
#foreach (var img in Model.Images)
{
<tr>
<td>
<img src="#Url.Content(img)"/>
</td>
</tr>
}
</table>
All the images in that folder are set in the Model property Images and I am Looping all the images and Displaying it in view.
This is my View
Test Upload File
<form action="#Url.Action("Index", "Home")" method="post" enctype="multipart/form-data">
#Html.AntiForgeryToken()
<label for="file">Filename:</label>
<input type="file" name="files" id="files" />
<input type="submit" name="submit" value="Upload" />
</form>
This is my Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(IEnumerable<HttpPostedFileBase> files)
{
if (files != null)
{
foreach (var file in files)
{
try
{
if (file != null && file.ContentLength > 0)
{
var fileName = file.FileName;
var path = Path.Combine(Server.MapPath(#"\Upload"), fileName);
file.SaveAs(path);
ViewBag.Message = "File uploaded successfully";
}
}
catch (Exception ex)
{
ViewBag.Message = "ERROR:" + ex.Message.ToString();
}
}
}
return View();
}
The problem is the HttpPostedFileBase files is always null. I cant find the problem.
Here is an example how to use form onsubmit method
Your HTML part
<form id="formTest" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="files" id="files" />
<input type="submit" name="submit" value="Upload" />
</form>
script
<script type="text/javascript">
var form = document.getElementById('formTest').onsubmit = function (e) {
e.preventDefault();
var formdata = new FormData(); //FormData object
var fileInput = document.getElementById('files');
if (fileInput != "" && fileInput.files.length > 0) {
//Iterating through each files selected in fileInput
for (i = 0; i < fileInput.files.length; i++) {
//Appending each file to FormData object
formdata.append(fileInput.files[i].name, fileInput.files[i]);
}
//Creating an XMLHttpRequest and sending
var xhr = new XMLHttpRequest();
var url = '#Url.Action("Index","Home")';
xhr.open('POST', url);
xhr.send(formdata);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var result = xhr.responseText;
}
}
return false;
}
}
</script>
C#
public ActionResult Index()
{
if (Request.Files.Count > 0)
{
var file = Request.Files[0];
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
file.SaveAs(path);
}
return View();
}
}
You can also handle files with Request.Files like this:
public ActionResult Index()
{
if (Request.Files.Count > 0)
{
var file = Request.Files[0];
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
file.SaveAs(path);
}
}
}
And for your second question, please try to use it between Html.BeginForm instead of form like this:
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<label>Filename:</label>
<input type="file" name="file1"/>
<input type="submit" name="submit" value="Upload" />
}
This is a part of my view code for Index action of Manage Controller.
<div class="mngimg">
#using (Html.BeginForm("UploadPhoto", "Manage", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="btn btn-default browseimg">
<input type="file" name="file" id="files" onchange="this.form.submit()" />
</div>
<div class="btn btn-default browseimg">
#Html.ActionLink("Remove Photo", "RemovePhoto", "Manage")
</div>
}
</div>
</div>
}
</dd>
<dt>Password:</dt>
<dd>
[
#if (Model.HasPassword) <!-- Here is my error. The Model is null -->
{
#Html.ActionLink("Change your password", "ChangePassword")
}
else
{
#Html.ActionLink("Create", "SetPassword")
}
]
</dd>
Whenever I open this page and click "Remove Photo" I keep getting an error saying that An exception of type 'System.NullReferenceException' occurred in App_Web_ckoryptg.dll but was not handled in user code. I tried debugging, but I am unable to figure out why my Model.HasPassword is becoming null. Here is my RemovePhoto Action from Manage Controller.
[HttpPost]
public async Task<ActionResult> UploadPhoto(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var user = await GetCurrentUserAsync();
var userId = user.Id;
var fileExt = Path.GetExtension(file.FileName);
var fnm = userId + ".png";
if (fileExt.ToLower().EndsWith(".png") || fileExt.ToLower().EndsWith(".jpg") || fileExt.ToLower().EndsWith(".gif"))// Important for security if saving in webroot
{
var filePath = HostingEnvironment.MapPath("~/Content/Images/") + fnm;
var directory = new DirectoryInfo(HostingEnvironment.MapPath("~/Content/Images/"));
if (directory.Exists == false)
{
directory.Create();
}
ViewBag.FilePath = filePath.ToString();
file.SaveAs(filePath);
return RedirectToAction("Index", new { Message = ManageMessageId.PhotoUploadSuccess });
}
else
{
return RedirectToAction("Index", new { Message = ManageMessageId.FileExtensionError });
}
}
return RedirectToAction("Index", new { Message = ManageMessageId.Error });// PRG
}
private async Task<ApplicationUser> GetCurrentUserAsync()
{
return await UserManager.FindByIdAsync(User.Identity.GetUserId());
}
I opened a default MVC project that comes with visual studio and I added these extra things that I followed from this tutorial ASP.NET upload images. How do I resolve this?
Edit:
This is my RemovePhoto action.
public ActionResult RemovePhoto()
{
string file = "~/Content/Images/" + User.Identity.GetUserId() + ".png";
if(System.IO.File.Exists(Server.MapPath(file)))
System.IO.File.Delete(Server.MapPath(file));
return View("Index");
}
Just Redirect back to your Index action. That way you don't have to instantiate your Index model in your RemovePhoto action. Can read more about this pattern here.
I have file upload html code as:
#using (Ajax.BeginForm("UploadImage", "PP", new AjaxOptions() { HttpMethod = "POST" }, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<input type="file" name="files">
<button class="buttoncss">Upload</button>
//<input type="submit" name="Submit to server">
(also tried with input type="submit"
}
In PPController i have method as below:
[HttpPost]
[ValidateAntiForgeryToken]
public void UploadImage(IEnumerable<HttpPostedFileBase> files)
{
if (files != null)
{
foreach (var file in files)
{
// Verify that the user selected a file
if (file != null && file.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(file.FileName);
// TODO: need to define destination
var path = Path.Combine(Server.MapPath("~/Upload"), fileName);
file.SaveAs(path);
}
}
}
But my controller method is not getting called.
What can be the problem?
Please help me.
i am doing my project in mvc4 using c#
i my project i want to upload two image files from a folder so i use the following code.
View:
<form action="" method="post" enctype="multipart/form-data">
<label for="file1">Filename:</label>
<input type="file" name="files" id="file1" />
<label for="file2">Filename:</label>
<input type="file" name="files" id="file2" />
<input type="submit" />
</form>
Controller:
[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> files) {
foreach (var file in files) {
if (file.ContentLength > 0) {
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads/Folder1"), fileName);
file.SaveAs(path);
}
}
return RedirectToAction("Index");
}
actually my need is that i want to upload these images in different folders on a single submit button. (That is file1 into Folder1 and file2 into Folder2) is that possible??
You have many solutions.
public ActionResult Index(IEnumerable<HttpPostedFileBase> files)
{
IList<HttpPostedFileBase> list = (IList<HttpPostedFileBase>)files;
for (int i = 0; i < files.Count(); i++)
{
if (list[i].ContentLength > 0 && i == 0)
{
var fileName = Path.GetFileName(list[i].FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads/Folder1"), fileName);
file.SaveAs(path);
}
else if (list[i].ContentLength > 0)
{
var fileName = Path.GetFileName(list[i].FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads/Folder2"), fileName);
file.SaveAs(path);
}
}
return RedirectToAction("Index");
}