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.
Related
at this moment I am uploading any file and saving it. What I want is to generate an error message if the user does not select any file and press the upload button, but at this moment the only thing it does is redirect to another view whether or not it has selected files. I would like to know if there is another better way to generate the upload of these files
this is my controller
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
[HttpPost]
public void Upload(HttpPostedFileBase file)
{
string file = (file.FileName).ToLower();
try
{
file.SaveAs(Server.MapPath("~/Uploads/" + file));
}
catch (Exception e)
{
ViewBag.UploadError = "Upload file error";
}
}
}
this is the view:
#{
ViewBag.Title = "Home";
}
#using (Html.BeginForm("Transformation", "Xml", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="col-md-12 offset-md-5">
<div class="custom-file col col-lg-2">
<input type="file" name="file" class="custom-file-input" id="inputGroupFile01" aria-describedby="inputGroupFileAddon01">
<label class="custom-file-label" for="inputGroupFile01">Choose file</label>
</div>
<div class="col-5">
<button class="btn btn-success col-md-4 mt-2" type="submit">Upload file</button>
</div>
</div>
//Message Error
<div class="alert alert-danger" role="alert">
<p class="text-danger">
#ViewBag.UploadError
</p>
</div>
}
#Thomas Caycedo Martinez, I believe you can simply modify your controller method like below.
If error, return to the same view with an error message.
Your view remains unchanged.
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if (file != null)
{
string fileName = (file.FileName).ToLower();
try
{
file.SaveAs(Server.MapPath("~/Uploads/" + fileName));
}
catch (Exception e)
{
ViewBag.UploadError = "Upload file error";
return View("Index");
}
}
else {
ViewBag.UploadError = "Upload file error";
return View("Index");
}
return View();
}
write the action and controller correctly
#using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
and check file in action
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if( file != null && file.Length > 0)
{
string file = (file.FileName).ToLower();
try
{
file.SaveAs(Server.MapPath("~/Uploads/" + file));
}
catch (Exception e)
{
ViewBag.UploadError = "Upload file error";
}
return View("Index");
}
else
{
//do something
return View("Index");
}
}
You can use JavaScript/JQuery to check for the same..
$(function(){
$("#btnSubmit").on("click",function(){
if($("#inputGroupFile01").val()==""){
alert("Please select a file")
return false;
}
})
})
where btnSubmit is the id for the submit button
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'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.
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");
}