I have a button on my website where users can upload multiple files onto the site. For some reason, in my controller the "file" variable always gets the value of NULL. I am able to upload files as a user, but my controller doesn't read that in for some reason. I'm not sure why and any guidance to the right direction would be greatly appreciated !
This is my cshtml:
<p id="FileArea"></p>
<input id="Files" name="Files" type="file" multiple="multiple" />
This is my model:
public IEnumerable<HttpPostedFileBase> Files { get; set; }
This is my controller:
foreach (var file in viewModel.Candidate.Files)
{
var file_s = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Files/location", file_s);
file_s.SaveAs(path);
}
Related
I build my form dynamically to allow multiple images to be uploaded, as per resolution requirements.
The RequiredDimensionsOptions collection has image requirements, eg. 1296x450, 916x450, etc. I loop through these and render a File upload control for each, thusly (abbreviated) - with a unique ID for each:
<form enctype="multipart/form-data" method="post" id="uploadFiles">
#foreach (var requiredDimension in Model.RequiredDimensionsOptions)
{ // the ID will be something like "file-0000w0000h"
<p>
<label for="file-#(requiredDimension.Width)w#(requiredDimension.Height)h">#requiredDimension.Width x #requiredDimension.Height</label>
<input class="forceLeftMargin" id="file-#(requiredDimension.Width)w#(requiredDimension.Height)h" name="file-#(requiredDimension.Width)w#(requiredDimension.Height)h" type="file">
</p>
}
<input type="submit" value="Upload files"/>
</form>
I can then get the files using some C#:
public async Task<IActionResult> OnPostAsync()
{
foreach (IFormFile? file in Request.Form.Files) // Request.Form.Files is empty when I set more than 1 upload control with a file
{
// work with the uploaded files
}
}
The problem is that when I try to upload more than one file using the controls, the files do not appear in the Request.Form collection as files or even as submitted fields. So this:
Request.Form.Keys.Any(q=>q.StartsWith("file-"))
... resolves to false. I have the single AntiForgeryRequestToken element. When I upload a single file, it works fine.
How can I have multiple files uploaded?
I appreciate I could use a multiple-file upload option, but I want to maintain the resolutions for validation and user experience.
This May help or give a closer solution:
in razor page .cshtml File.
#page
#model KafilWepAdmin.Pages.testingModel
#{
var RequiredDimensionsOptions = new Dictionary<int, int>() { {1296, 450 }, { 916, 450 } };
}
<form method="post" enctype="multipart/form-data">
#foreach (var requiredDimension in #RequiredDimensionsOptions)
{
<div>
<label for=$"w{#requiredDimension.Key}h{#requiredDimension.Value}">#requiredDimension.Key x #requiredDimension.Value</label>
<input type="file" class="forceLeftMargin" id=$"w{#requiredDimension.Key}h{#requiredDimension.Value}" name=$"w{#requiredDimension.Key}h{#requiredDimension.Value}">
</div>
}
<button type="submit" asp-page-handler="GetFiles">Upload Files</button>
</form>
in .cs File
public async Task<IActionResult> OnPostGetFilesAsync()
{
var files = Request.Form.Files;
foreach (var file in files)
{
// process the file
}
return Page();
}
I have found some questions like Validate Image Type but it didn't fulfill my needs.
I have Model class named Movie which contains property
public byte[] Image { get; set; }
My View contains
<form asp-action="Index" method="post" enctype="multipart/form-data">
<input asp-for="Image" type="file" id="files" class="form-control" />
<input type="submit" value="Create" class="btn btn-default" />
</form>
and in controller, I am converting it to bytes and storing it in database. I want to validate it like, Files allowed .jpg, .jpeg, .png and max size of file 5Mb.
[HttpPost]
public async Task<IActionResult> Index(Movie Movie, List<IFormFile> Image)
{
foreach(var item in Image)
{
if (item.Length > 0)
{
using (var stream = new MemoryStream())
{
await item.CopyToAsync(stream);
Movie.Image = stream.ToArray();
}
}
}
_applicationDbContext.Movie.Add(Movie);
_applicationDbContext.SaveChanges();
return View();
}
How can I validate the uploaded file ?
Every file has an extension and if it is a binary file, it has magic numbers in the header of the file that indicates what type of file it is, You can identify file type by reading the header of bytes.
Check this GitHub code
https://github.com/Muraad/Mime-Detective
file headers reference:
http://www.garykessler.net/library/file_sigs.html
mime types reference:
http://www.webmaster-toolkit.com/mime-types.shtml
I'm working on a ASP.NET MVC site that will allow a user to upload multiple images to a gallery. After a user uploads their images and before they are saved to the database, the user will have the ability to reorder the images using a jQuery drag and drop. The user can then submit their uploads. The user will also have the ability later on to edit their gallery and again have the ability to reshuffle the order of their images. I will not be saving the images to the database, just the filenames. I'm not sure how to best handle this. I'm thinking the POST controller will take a List<HttpPostedFileBase> parameter, and then convert to a byte [] array to maintain the image order. Then save the image names to the database as a comma separated string? What would the most efficient way to handle this be?
Alright so if we put drag and drop a side, see this as your view:
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="files" value="" multiple="multiple"/>
<input type="submit" value="Upload"/>
}
In your controller:
[HttpPost]
public ActionResult Index(HttpPostedFileBase[] files)
{
try
{
foreach (HttpPostedFileBase file in files)
{
string name = System.IO.Path.GetFileName(file.FileName);
file.SaveAs(Server.MapPath("~/Images/" + name));
string filename = "Images/" + name;
//Save the the filename to your database
}
}
catch
{
throw ex;
}
return View();
}
This question already has answers here:
How to get full path of selected file on change of <input type=‘file’> using javascript, jquery-ajax?
(14 answers)
Closed 6 years ago.
I have the following razor code:
<div class="container">
#Html.ValidationSummary(false)
#using (Html.BeginForm("EncryptFile", "Encryption", new { returnUrl = Request.Url.AbsoluteUri }, FormMethod.Post, new { #id = "encryptionform", #class = "form-horizontal" }))
{
<div class="form-group">
#Html.Label("File", new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" id="encryptfilefield" name="uploadedfile" enctype='multipart/form-data'/>
</div>
</div>
<button type="submit" id="encryptfilebutton">Encrypt</button>
<button id="decryptfilebutton" type="button">Decrypt</button>
<button id="reencryptfilebutton" type="button">Re-Encrypt</button>
}
</div>
and the following controller code gets called when I click the Encrypt button:
[HttpPost]
public ActionResult EncryptFile(string uploadedfile)
{
/*process the file without uploading*/
return Json(new { status = "success", message = "Encrypted!" });
}
I am able to hit this action when I click the encrypt button, but the uploadedfile string always comes in as null. How can I get the fill filepath of the file that was selected? Please note that I am not trying to upload it to the server (despite "uploaded" appearing in the name), I just need the filepath.
EDIT
I saw in IE 11 that the following showed the file path fully (the part inside the alert):
alert($("#encryptfilefield").val());
However this is not a full solution, and it seems there is no solution due to to it being a security issue.
Thank you.
Updated Answer
Unfortunately there's no way to get that info consistently among all browsers., there's multiple posts on here about this topic and the conclusion is browsers don't allow it for security purposes.
I did find that in IE 11 they do include the path within the input dom element .value property, but I don't know if that works in other versions, and it does not work in chrome.
$('input[type=file]').change(function () {
console.dir(this.value);
console.dir(this.files[0])
})
Unfortunately that's about the best you can expect. Here's a post that has a couple things you could do to possibly achieve some very specific scenarios.
How to get full path of selected file on change of <input type=‘file’> using javascript, jquery-ajax?
Original Answer (how to get file path "After" it reaches server)
The null param issue I'm thinking is because MVC binds on element name property.
<input type="file" id="encryptfilefield" name="uploadedfile" enctype='multipart/form-data'/>
and your controller action is marked as type string, which is not what your input type is.
you could either change that to this,
[HttpPost]
public ActionResult EncryptFile(HttpPostedFileBase uploadedfile)
{
or try grabbing the file straight from the Request object like below, you'd have to save it somewhere before you get the full path of it though, i don't believe you'll get the filepath of where it originated from, only after you save it.
[HttpPost]
public ActionResult EncryptFile(string uploadedfile)
{
HttpPostedFileBase myfile = Request.Files[0];
if (file.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(file.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"),fileName);
file.SaveAs(path);
}
/*process the file without uploading*/
return Json(new { status = "success", message = "Encrypted!" });
}
Currently, I'm working on asp.net mobile website and I've to implement one functionality related to upload file in mobile website.
I'm using asp:upload Control but, It's not working in mobile website.
I have been searching in google for this issue since last week, But I can't find any relative source or blog.
Can anyone help me on this topic?
In view:
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="OK" />
}
In Control:
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
// Verify that the user selected a file
if (file != null && file.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(file.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
}
// redirect back to the index action to show the form once again
return RedirectToAction("Index");
}
and remove the jquerymobile script from your page. Like in MVC4
#Scripts.Render("~/bundles/jquery", "~/bundles/jquerymobile")
Remove this line, it's the source of the conflict.