HTTPPostedFileBase is always null in the controller. Please review and let me know where am I wrong.
Controller Post method
public ActionResult EditProfile(Contact model, HttpPostedFileBase picture, string currentPassword, string CurrentPasswordQ, string newPassword, string loginPwd, string currentPinQ, string newPin, int? selectedQuestion, string answer, bool pwdChange = false, bool questionChange = false, bool pinChange = false)
{
My Form Header
#using (Html.BeginForm("EditProfile", "CompanyAdmin", FormMethod.Post, new { enctype = "multipart/form-data", #data_ajax = "false" }))
{
And my file Input
<tr>
<td class="label_form_div">
<label>Profile Picture</label>
</td>
<td>
<input type="file" name="picture" />
</td>
</tr>
Please review and see if you can find what is wrong with this.
Thanks
Its seems your code is correct, anyway try this way in the controller. It might helpful for you:
public ActionResult EditProfile(Contact model, string currentPassword, string CurrentPasswordQ, string newPassword, string loginPwd, string currentPinQ, string newPin, int? selectedQuestion, string answer, bool pwdChange = false, bool questionChange = false, bool pinChange = false)
{
if (Request.Files != null && Request.Files.Count > 0)
{
HttpPostedFileBase file = Request.Files[0];
if (file != null && file.ContentLength > 0)
{
//other logic
}
}
}
Source: https://stackoverflow.com/a/32219011/3397630
Please follow the below steps.
Step :- 1
#using (Html.BeginForm("FileUpload", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<label for="file">Upload Image:</label>
<input type="file" name="file" id="file" style="width: 100%;" />
<input type="submit" value="Upload" class="submit" />
}
Step :- 2
public ActionResult FileUpload(HttpPostedFileBase file)
{
if (file != null)
{
string pic = System.IO.Path.GetFileName(file.FileName);
string path = System.IO.Path.Combine(
Server.MapPath("~/images/profile"), pic);
// file is uploaded
file.SaveAs(path);
// save the image path path to the database or you can send image
// directly to database
// in-case if you want to store byte[] ie. for DB
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
byte[] array = ms.GetBuffer();
}
}
// after successfully uploading redirect the user
return RedirectToAction("actionname", "controller name");
}
Related
I'm following this example on the MS website for File Uploads using Razor and C#.
If I have more than one File upload buttons, how would the C# code know which button the uploaded file is from? Based on the button the file was uploaded from, I will be saving files to specific folders.
https://learn.microsoft.com/en-us/aspnet/web-pages/overview/data/working-with-files
#using Microsoft.Web.Helpers;
#{
var fileName = "";
if (IsPost) {
var fileSavePath = "";
var uploadedFile = Request.Files[0];
fileName = Path.GetFileName(uploadedFile.FileName);
fileSavePath = Server.MapPath("~/App_Data/UploadedFiles/" +
fileName);
uploadedFile.SaveAs(fileSavePath);
}
}
<!DOCTYPE html>
<html>
<head>
<title>FileUpload - Single-File Example</title>
</head>
<body>
<h1>FileUpload - Single-File Example</h1>
#FileUpload.GetHtml(
initialNumberOfFiles:1,
allowMoreFilesToBeAdded:false,
includeFormTag:true,
uploadText:"Upload")
#if (IsPost) {
<span>File uploaded!</span><br/>
}
</body>
</html>
The way to do this is to name the buttons the same, but give them different values. You can then do a case statement and direct the logic based on the value.
Razor
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="FirstUpload" />
<input type="submit" name="submitID" id="submitID" value="Upload1" />
<input type="file" name="SecondUpload" />
<input type="submit" name="submitID" id="submitID" value="Upload2" />
}
Controller
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(FormCollection collection)
{
string btn = Request.Params["submitID"];
switch (btn)
{
case "Upload1":
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
}
break;
case "Upload2":
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
}
break;
}
return View();
}
I had a similar problem and ended up with following code:
Razor
//BeginForm and other staff
#foreach (var d in Model.Types)
{
<input type="file" name="doc:#d.Id:upload" />//#d.Id is the key point
<button formenctype="multipart/form-data"
type="submit" formaction="/MyController/uploaddoc"
name="typeid" formmethod="post" value="#d.Id">//this way I send Id to controller
Upload
</button>
}
MyController
[HttpPost]
[ValidateAntiForgeryToken]
[Route("mycontroller/uploaddoc")]//same as formaction
public async Task<ActionResult> UploadDoc(FormCollection data, int typeid)
{
//restore inpput name
var fl = Request.Files["doc:" + typeid.ToString() + ":upload"];
if (fl != null && fl.ContentLength > 0)
{
var path = Server.MapPath("~/app_data/docs");
var fn = Guid.NewGuid().ToString();//random name
using (FileStream fs = System.IO.File.Create(Path.Combine(path, fn)))
{
await fl.InputStream.CopyToAsync(fs);
}
}
}
I want to upload a profile picture to my system.But I click upload, "Server Error in '/' Application" message appears. Also I have figured out the URL is little bit different than Correct URL should be like this.
/ProfileController/UploadPhoto
But the URL in the here is /admin/ProfileController/UploadPhoto
What should do in order to make this work?
This is my code in controller
[HttpPost]
public ActionResult UploadPhoto(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var user = Session["userID"].ToString();
var fileExt = Path.GetExtension(file.FileName);
var fileName = user + ".png";
if (fileExt.ToLower().EndsWith(".png") || fileExt.ToLower().EndsWith(".jpg"))
{
var filePath = HostingEnvironment.MapPath("~/Content/images/profile/") + fileName;
var directory = new DirectoryInfo(HostingEnvironment.MapPath("~/Content/images/profile/"));
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 });
}
This is the code in view
<dl class="dl-horizontal">
<dd>
#if (User != null)
{
var imgUrl = Url.Content("Content/Images/" + User + ".png") + "?time=" + DateTime.Now.ToString();
<div class="input-field col s12">
<div class="input-field col s12">
<img src="#imgUrl" height="250" width="250" />
</div>
<div class="mngimg">
#using (Html.BeginForm("UploadPhoto", "ProfileController", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="input-field col s12">
<input type="file" name="file" id="files" onchange="this.form.submit()" />
</div>
}
</div>
</div>
}
</dd>
</dl>
RouteConfig.cs
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"AdminPanel",
"admin/{controller}/{action}/{id}",
new {`controller="Home", action = "Index", id = UrlParameter.Optional },
new[] { "OnlineElection.Controllers.Admin" } );
routes.MapRoute(
name:"Default",
url:"{controller}/{action}/{id}",
defaults:new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces:new[] { "OnlineElection.Controllers" }
);
The form URL you're posting to is invalid.
When using Controllers, you omit the Controller word and use only the name of the controller, in this case ProfileController becomes just Profile, this also counts for URL's.
Your Html.BeginForm should in fact be
#using (Html.BeginForm("UploadPhoto", "Profile", FormMethod.Post, new { enctype = "multipart/form-data" }))
Hi to all of you I am facing a problem on uploading a file and saving it into a folder here is my view
<div class="admin-empty-dashboard">
#using (Html.BeginForm("UploadResumes", "Employee", new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="icon">
<i class="ion-ios-book-outline"></i>
</div>
<h4>Welcome #Model.FullName!</h4>
<p>#ViewBag.Error</p>
<div class="form-group bootstrap-fileinput-style-01">
<label>Upload Resume</label>
<input type="file" name="file" required="required" class="btn btn-primary" style="margin-left:265px" accept="application/msword,text/plain, application/pdf">
<span class="font12 font-italic">** File must not bigger than 2MB</span>
</div>
<input type="submit" name="name" class="btn btn-primary" value="UploadResumes" />
}
</div>
and here is my controllers action problem is that it HttpPostedFileBase object value is always null and i ran Request.Files.Count it's also giving me zero where is problem?
public ActionResult UploadResumes(HttpPostedFileBase file)
{
if (Session["UserID"] != null && Session["UserName"] != null && Session["EmployeeID"] != null)
{
int id = Convert.ToInt32(Session["EmployeeID"]);
string[] allowedExtenssions = new string[] { ".pdf", ".doc", ".docx" };
string cvPath = "~/cvs/Employee_cvs/";
if (!Directory.Exists(Server.MapPath(cvPath)))
Directory.CreateDirectory(Server.MapPath(cvPath));
MyDbContext db=new MyDbContext();
tblEmployee employee = (from s in db.tblEmployees where s.UserId == id select s).FirstOrDefault();
// HttpPostedFileBase cv = Request.Files["CV"];
if (file != null)
{
if (file.ContentLength > 0)
{
string ext = Path.GetExtension(file.FileName);
if (allowedExtenssions.Contains(ext.ToLower()))
{
string fileName = DateTime.Now.Ticks + ext;
string filePath = cvPath + fileName;
string serverPath = Server.MapPath(filePath);
file.SaveAs(serverPath);
employee.cvUrl = filePath;
}
}
ViewBag.Error = "Some Error Occured";
}
return RedirectToAction("Dashboard");
}
else
{
return RedirectToAction("Login", "User");
}
}
Update like below and check
#using (Html.BeginForm("UploadResumes", "Employee",FormMethod.Post, new { enctype = "multipart/form-data" }))
{
}
Also
[HttpPost]
public ActionResult UploadResumes(HttpPostedFileBase file)
{
}
Try changing your parameters on your controller to
public ActionResult UploadResumes(Model yourModel, HttpHostedFileBase file)
In most of my controllers that require a file for upload, are usually array based. Make you function parameters an array like this:
public ActionResult UploadResumes(HttpPostedFileBase[] files){
}
I have a cshtml page that has a form which sends data to an HTTPHandler. If I run into some kind of error I want to respond with an error message and display it in the same cshtml page. How can I do this?
Here is my handler
public void ProcessRequest(HttpContext context)
{
var mode = context.Request.Form["mode"];
var title = context.Request.Form["postTitle"];
var content = context.Request.Form["postContent"];
var slug = context.Request.Form["postSlug"];
var id = context.Request.Form["postId"];
var datePublished = context.Request.Form["postDatePublished"];
if (string.IsNullOrWhiteSpace(slug))
{
slug = CreateSlug(title);
}
if (mode == "edit")
{
EditPost(Convert.ToInt32(id), title, content, slug, datePublished, 1);
}
else if (mode == "new")
{
CreatePost(title, content, slug, datePublished, 1);
}
context.Response.Redirect("~/admin/post/");
}
private static void CreatePost(string title, string content,
string slug, string datePublished, int authorId)
{
var result = PostRepository.Get(slug);
DateTime? published = null;
if (result != null)
{
throw new HttpException(409, "Slug is already in use.");
}
if (!string.IsNullOrWhiteSpace(datePublished))
{
published = DateTime.Parse(datePublished);
}
PostRepository.Add(title, content, slug, published, authorId);
}
private static void EditPost(int id, string title, string content,
string slug, string datePublished, int authorId)
{
var result = PostRepository.Get(id);
DateTime? published = null;
if (result == null)
{
throw new HttpException(404, "Post does not exist.");
}
if (!string.IsNullOrWhiteSpace(datePublished))
{
published = DateTime.Parse(datePublished);
}
PostRepository.Edit(id, title, content, slug, published, authorId);
}
private static string CreateSlug(string title)
{
title = title.ToLowerInvariant().Replace(" ", "-");
title = Regex.Replace(title, #"[^0-9a-z-]", string.Empty);
return title;
}
And here is the form in the cshtml file
var post = Post.Current;
<div>
<form name="post" method="post" action="~/admin/post.ashx">
<input type="hidden" name="mode" value="#mode" />
<input type="hidden" name="postId" value="#post.Id" />
<p>Title: <input type="text" name="postTitle" value="#post.Title" /></p>
<p>Content: <textarea name="postContent">#post.Content</textarea></p>
<p>Slug: <input type="text" name="postSlug" value="#post.Slug" /></p>
<p>Date Published: <input type="text" name="postDatePublished" value="#post.DatePublished" /></p>
<p><input type="submit" name="postSubmit" value="Submit" /></p>
</form>
</div>
For example: Right now I'm throwing an exception if the post slug already exists. How would I send an error message that says "Slug is already in use" and then display it on the cshtml page preferably right on top of the form? Thanks.
There are similar posts out there but they do not seem to represent my situation. Apologies in advance if this is a re-post.
I have my view as
#FileUpload.GetHtml(initialNumberOfFiles:1,allowMoreFilesToBeAdded:true,includeFormTag:true, uploadText: "Upload" )
#model IEnumerable<EpubsLibrary.Models.Partner>
#{ using (Html.BeginForm("Index","Epub"))
{
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
<input type="submit" value="send" id="pickPartner" hidden="hidden"/>
}
}
<script type="text/javascript">
$(".file-upload-buttons input").click(function () {
$("#pickPartner").click();
});
</script>
my controller is
[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> fileUpload, FormCollection collection)
{
int selectedPartner, count =0;
//int selectedPartner = int.Parse(collection["PartnerID"]);
if(!int.TryParse(collection["PartnerID"], out selectedPartner))
{
selectedPartner = 0;
ModelState.AddModelError("", "You must pick a publishing agency");
}
IList<Partner> p = r.ListPartners();
ViewBag.Partners = new SelectList(p.AsEnumerable(), "PartnerID", "Name", selectedPartner);
//make sure files were selected for upload
if (fileUpload != null)
{
for (int i = 0; i < fileUpload.Count(); i++)
{
//make sure every file selected != null
if (fileUpload.ElementAt(i) != null)
{
count++;
var file = fileUpload.ElementAt(i);
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
// need to modify this for saving the files to the server
var path = Path.Combine(Server.MapPath("/App_Data/uploads"), Guid.NewGuid() + "-" + fileName);
file.SaveAs(path);
}
}
}
}
if (count == 0)
{
ModelState.AddModelError("", "You must upload at least one file!");
}
return View();
}
I am using the file upload helper from Microsoft Web Helpers to upload files. The problem I am having is the helper created a form and I have another form I need to submit data from as well on the same page.
I thought I could link the submit buttons so that when you click upload it also sent the other form data but the data is not being sent. Each form works independently of the other with no issue but I need them to work together. Any advice would be appreciated.
Ok I updated the view with
#model IEnumerable<EpubsLibrary.Models.Partner>
#{ using (Html.BeginForm("Index","Epub"))
{
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
#FileUpload.GetHtml(initialNumberOfFiles: 1, allowMoreFilesToBeAdded: true, includeFormTag: false, uploadText: "Upload")
<input type="submit" value="send" id="pickPartner"/>
}
}
But now the file data does not seem to be getting passed anymore.
-- Update --
I have made the following changes.
The view now looks like
#model IEnumerable<EpubsLibrary.Models.Partner>
#{ using (Html.BeginForm("Index", "Epub", new { enctype = "multipart/form-data" }))
{
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
#FileUpload.GetHtml(initialNumberOfFiles: 1, allowMoreFilesToBeAdded: true, includeFormTag: false, uploadText: "Upload")
<input type="submit" value="send" id="pickPartner"/>
}
}
and the controller
[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> fileUpload, int PartnerID = 0)
//public ActionResult Index(IEnumerable<HttpPostedFileBase> fileUpload, FormCollection collection)
{
int count =0;
IList<Partner> p = r.ListPartners();
ViewBag.Partners = new SelectList(p.AsEnumerable(), "PartnerID", "Name", PartnerID);
//make sure files were selected for upload
if (fileUpload != null)
{
for (int i = 0; i < fileUpload.Count(); i++)
{
//make sure every file selected != null
if (fileUpload.ElementAt(i) != null)
{
count++;
var file = fileUpload.ElementAt(i);
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
// need to modify this for saving the files to the server
var path = Path.Combine(Server.MapPath("/App_Data/uploads"), Guid.NewGuid() + "-" + fileName);
file.SaveAs(path);
}
}
}
}
if (count == 0)
{
ModelState.AddModelError("", "You must upload at least one file!");
}
return View();
}
}
I am trying to figure out how the file data is getting sent over in the post (if it is) so I can save the files.
-- Final Update with Answer --
Well the problem turned out to be two fold.. 1st the issue with #FileUpload and needing to set includeFormTag: false
The other problem I discovered was I needed to make sure in my #Html.BeginForm I included FormMethod.Post This was discovered when the fileUpload count kept coming back as 0. I ran the profiler on firebug and it pointed out that the file data was not actually getting posted. Here is the corrected code below.
my view
#model IEnumerable<EpubsLibrary.Models.Partner>
#{ using (Html.BeginForm("Index", "Epub", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
#FileUpload.GetHtml(initialNumberOfFiles: 1, allowMoreFilesToBeAdded: true, includeFormTag: false, uploadText: "Upload")
<input type="submit" value="send" id="pickPartner"/>
}
}
my controller
[HttpPost]
public ActionResult Index(IEnumerable<HttpPostedFileBase> fileUpload, int PartnerID = 0)
{
int count =0;
IList<Partner> p = r.ListPartners();
ViewBag.Partners = new SelectList(p.AsEnumerable(), "PartnerID", "Name", PartnerID);
//make sure files were selected for upload
if (fileUpload != null)
{
for (int i = 0; i < fileUpload.Count(); i++)
{
//make sure every file selected != null
if (fileUpload.ElementAt(i) != null)
{
count++;
var file = fileUpload.ElementAt(i);
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
// need to modify this for saving the files to the server
var path = Path.Combine(Server.MapPath("/App_Data/uploads"), Guid.NewGuid() + "-" + fileName);
file.SaveAs(path);
}
}
}
}
if (count == 0)
{
ModelState.AddModelError("", "You must upload at least one file!");
}
return View();
}
Thank you #Jay and #Vasile Bujac for your help with this.
Set IncludeFormTag to false and put it inside your other form using.
#model IEnumerable<EpubsLibrary.Models.Partner>
#{ using (Html.BeginForm("Index","Epub"))
{
#FileUpload.GetHtml(initialNumberOfFiles:1,allowMoreFilesToBeAdded:true,includeFormTag:false, uploadText: "Upload" )
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
<input type="submit" value="send" id="pickPartner" hidden="hidden"/>
}
}
Update:
Try changing the signature of your view to this:
public ActionResult Index(IEnumerable<HttpPostedFileBase> fileUpload, int PartnerID = 0)
Check the overloads for FileUpload.GetHtml and see if there is a parameter to set the field name for your file uploads. Previously it was just the files being uploaded, now its files and a parameter, so naming becomes more important.
You should use the same form for dropdownlist and file inputs. You can do this by putting the FileUpload helper inside the form, and setting "includeFormTag" parameter to false.
#model IEnumerable<EpubsLibrary.Models.Partner>
#using (Html.BeginForm("Index","Epub")) {
#FileUpload.GetHtml(initialNumberOfFiles:1,allowMoreFilesToBeAdded:true,includeFormTag:false, uploadText: "Upload" )
#Html.DropDownList("PartnerID", (IEnumerable<SelectListItem>)ViewBag.Partners, "None")
<input type="submit" value="send" id="pickPartner" hidden="hidden"/>
}