I'm currently trying to handle the upload of two different files from two different <input type="file"/>s.
For example:
#using (Html.BeginForm("AddIssue", "Magazine", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<fieldset>
<div class="editor-field">
<div class="editor-label">Issue: </div>
<input type="file" name="issueFile" id="issueFile"/>
</div>
<div class="editor-field">
<div class="editor-label">Cover: </div>
<input type="file" name="issueCover" id="issueCover"/>
</div>
<button type="submit">Save</button>
</fieldset>
}
I've figured out how to receive a file (or files) from one input, but can't find any appropriate information on how to receive files from multiple inputs.
I already have a method for POST, but can't figure out what shall I receive on post.
[HttpPost, Authorize]
public ActionResult AddIssue(string dummy)
{ }
After the comment, here is a more specific solution...
You need to ensure that your Controller Action parameters are named the same as the name attribute on your form fields. This should work for you:
public ActionResult AddIssue(HttpPostedFileBase issueFile, HttpPostedFileBase issueCover)
{ }
Remember, it is the name attributes that are used to identify the fields from the controller. The id attributes mean nothing, and do not have to match.
Related
I try to make #Html.EditorFor(model => model.file) to put file on web page (file is IFormFile type) in my ASP.NET Core application. But file is null, when i click submit,for some reason, and exception arises.For string everything is OK. Here is HTML code:
#using (Html.BeginForm("tt", "Home", FormMethod.Post))
{
<div class="row">
<div class="col-md-4">
#Html.EditorFor(model => model.file)
</div>
<div class="col-md-8">
<button type="submit" id="btnUpload" class="btn btn-primary">Upload</button>
</div>
</div>
<br />
<div>#Html.DisplayFor(model => model.content)</div>
}
controller code:
public ActionResult tt(Models.FileInfo f)
{
var r = f.content1 + f.file.FileName;
f.content = r;
return View("Demo_index", f);
}
and model:
public class FileInfo
{
public IFormFile file { get; set; }
public string content { get; set; }
public string content1 { get; set; }
}
Is it possible to make #Html.EditorFor(model => model.file) work? Or is there some similar way to make form with file uploading?
The issue is that you're posting as x-www-form-urlencoded, which doesn't support file uploads. You need to use multipart/form-data, instead, which can be achieved via adding the enctype attribute to your form tag:
<form ... enctype="multipart/form-data">
This is possible using Html.BeginForm, but you have to use an overload that requires you to specify a ton of parameters, and it's more pain than it's worth. Besides, in Core, using the tag helpers is much better anyways. Literally all you need is:
<form asp-action="tt" asp-controller="Home" method="post" enctype="multipart/form-data">
...
</form>
If you're doing a postback, i.e. to the same page you're already on, you can remove the asp-action and asp-controller attributes entirely. This will be processed by the built-in FormTagHelper and the right action and such will be generated for you.
FWIW, the same applies with your input as well. Instead of EditorFor, you can simply do:
<input asp-for="file" />
The InputTagHelper will fill in everything else.
I have a small tool that downloads reports based on the specified options. The download works well. And now, I want to also upload a file to the folder and then further use it.
The problem is that I already have one submit button on the form that is used for the download and when I am adding another button for the upload, only download is triggered.
I tried to resolve it using an #Html.ActionLink(), but no success. Is there any proper way to resolve the issue? I know that there is a possibility to capture the submit value and then check in one main ActionResult in the Controller and redirect to the respective ActionResult, but I don't want to do it, since there are too many POST Actions in one controller.
Here is my View - download.cshtml:
#using (Html.BeginForm())
{
<fieldset>
<div class="title">Click to download report</div>
<div class="field">
<input id="downloadBtn" type="submit" class="button" value="Download" />
</div>
</fieldset>
<fieldset id="Option_ClientInfo">
<div class="title">
Image
</div>
<div class="field">
<input type="file" name="ImageUpload" accept="image/jpeg" />
<p>#Html.ActionLink("Upload", "UploadImage", new { controller = "Home", enctype = "multipart/form-data"}, new { #class = "button" })</p>
</div>
</fieldset>
}
And the controller - HomeController.cs:
public partial class HomeController : Controller
{
// some functions
// ....
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UploadImage(HttpPostedFileBase imageFile)
{
string path = Path.Combine(this.GetImageFolder, Path.GetFileName(imageFile.FileName));
imageFile.SaveAs(path);
return null;
}
// additional POST functions for other forms
// ....
[HttpPost]
public ActionResult Download(Info downloadInfo)
{
// perform checks and calculations
return new reportDownloadPDF(downloadInfo);
}
}
Any suggestion in appreciated.
The solution is just separate upload and download functionalities using two forms so it wont conflict while submitting.
#using (Html.BeginForm())
{
<fieldset>
<div class="title">Click to download report</div>
<div class="field">
<input id="downloadBtn" type="submit" class="button" value="Download" />
</div>
</fieldset>
<fieldset id="Option_ClientInfo">
<div class="title">
Image
</div>
</fieldset>
}
#using (Html.BeginForm("UploadImage", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<fieldset>
<div class="field">
<input type="file" name="ImageUpload" accept="image/jpeg" />
<p>
<input id="uploadBtn" type="submit" class="button" value="Upload" />
</p>
</div>
</fieldset>
}
There is another issue as well. Image control name and Post Action method parameter name should be same.
So your upload image Post Action method will be:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UploadImage(HttpPostedFileBase imageUpload)
{
string path = Path.Combine(this.GetBasePath + "/img/tmp/", Path.GetFileName(imageFile.FileName));
imageFile.SaveAs(path);
return null;
}
I want to upload multiple files including Word Documents, Pdf and Images.
I need to use a single input for files because we don't know how many files will be uploaded.
My code is this but I have problem that I can't send files to server side.
Controller Code :
public ActionResult Create([Bind(Include = "Id,Content")] Message message, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
// Object save logic
SaveFiles(message,files);
return RedirectToAction("Index");
}
return View(message);
}
Part of view code :
<form name="registration" action="">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<label for="Content" >Content:</label>
<textarea class="form-control compose_content" rows="5" id="Content" name="content"></textarea>
<div class="fileupload">
Attachment :
<input id="files" name="files" type="file" multiple />
</div>
</div>
<button type="submit" class="btn btn-default compose_btn" >Send Message</button>
</form>
I don't have problem with saving files and saving the object.
only problem :
files list is null.
I order to upload files, your form needs to include the enctype= multipart/form-data attribute.
<form name="registration" action="" enctype= "multipart/form-data">
or better
#using (Html.BeginForm(actionName, controllerName, FormMethod.Post, new { enctype= "multipart/form-data" }))
and I strongly recommend you pass a model to the view and use the strongly typed HtmlHelper methods to create your html for the properties of your model.
I'm trying to upload multiple images on one form
#using (Html.BeginForm("Create", "AdminRestaurants", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
<label for="logoFile" class="col-sm-2 control-label">Logo:</label>
<div class="col-sm-6">
<input type="file" multiple="" name="logoFile" id="logoFile" />
</div>
</div>
<div class="form-group">
<label for="fohFile" class="col-sm-2 control-label">FOH Logo:</label>
<div class="col-sm-6">
<input type="file" multiple="" name="fohFile" id="fohFile" />
</div>
</div>
<div class="form-group">
<label for="bohFile" class="col-sm-2 control-label">BOH Logo:</label>
<div class="col-sm-6">
<input type="file" multiple="" name="bohFile" id="bohFile" />
</div>
</div>
<div class="form-group">
<label for="mgmFile" class="col-sm-2 control-label">MGM Logo:</label>
<div class="col-sm-6">
<input type="file" multiple="" name="mgmFile" id="mgmFile" />
</div>
</div>
I'm trying to process the form on the controller with this
public ActionResult Create(IEnumerable<HttpPostedFileBase> files, RestaurantModel collection)
{
if (ViewData.ModelState.IsValid)
{
}
}
Currently nothing shows up in the files signature on the controller. This seems to work great when only working with one file
public ActionResult Create(HttpPostedFileBase file, EventsModel collection)
Can someone point me in the direction to allow multiple files to be uploaded with one submission form?
Your problem is that you form creates a post request with information that the model binder can bind because the naming convention is not right.
you see, you have 4 file fields each with a different name, for the model binder to bind them correctly your controller action signature should look like this:
public ActionResult Create(HttpPostedFileBase mgmFile,
HttpPostedFileBase logoFile,
HttpPostedFileBase fohFile ,
HttpPostedFileBase bohFile)
Following MCV design pattern The best option would be to use a ViewModel that holds an IEnumerable<HttpPostedFileBase>
and you would create a custom editor template for an IEnumerable<HttpPostedFileBase>
so that you could use it like that:
Html.EditorFor(m=>Model.filesUploaded)
and your controller action would look like this:
public ActionResult Create(MyViewModel i_InputModel)
{
i_InputModel.filesUploade; //Use the files here to upload them.
}
Other options are:
Use the HTML5 multiple attribute on the file input field like this:
<label for="mgmFile" class="col-sm-2 control-label">Files:</label>
<div class="col-sm-6">
<input type="file" multiple="multiple" name="files" id="files" />
</div>
and a controller action like this:
public ActionResult Create(HttpPostedFileBase files)
or use multiple file fields but index them in their name:
<input type="file" multiple="multiple" name="files[0]" id="files_1" />
<input type="file" multiple="multiple" name="files[1]" id="files_2" />
<input type="file" multiple="multiple" name="files[2]" id="files_3" />
<input type="file" multiple="multiple" name="files[3]" id="files_4" />
and then you could use a controller action like this:
public ActionResult Create(IEnumerable<HttpPostedFileBase> files)
This would only work if your file inputs had indexed names like files[0], files[1], files[2],...
In order to understand how model binding to a list works in asp.net mvc, I recommend that you read this post: Model Binding to a List
You don't even have to use model binding to get the files. Use Request.Files in your Action to get them.
public ActionResult Create(EventsModel collection)
{
var files = Request.Files;
// rest of the code...
}
<td>
<input type="file" name="files" id="files" multiple="multiple" />
</td>
As Here, I demonstrate with simple example : http://www.infinetsoft.com/Post/How-to-create-multiple-fileUpload-using-asp-net-MVC-4/1229#.V0J-yfl97IU
This is sort of a follow up to Bind value to model in Asp.Net MVC Application.
I have a Model with different control classes. The relevant code:
public class FileUploadModel
{
public HttpPostedFileBase File { get; set; }
}
I have a partial view with the following relevant code:
#Html.TextBoxFor(x => x.File, new { type = "file", id = "File", name = "File" })
Then there is a main view in which the partial view is rendered with the following relevant code:
#using (Ajax.BeginForm("ActionMethods", "Index", new AjaxOptions { UpdateTargetId = "parameterList" }, new { enctype = "multipart/form-data" }))
{
<div id="parameterList">
<div id="verifyBtnDiv" style="display:none;">
**THIS IS WHERE THE PARTIAL VIEW AS SHOWN ABOVE WOULD BE RENDERED**
<input type="submit" id="verifyBtn" value="Verify"/>
</div>
</div>
}
Now when the submit happens, the file does not binds to the model property. The control passes to the controller but i debug and see that its null. ANy suggestions regarding this?
There are a few issues with the code you posted that will prevent what you are attempting to do from working.
First, I am pretty certain that you cannot use the #Html.TextBoxFor helper and convert it to a file input. If it works now, I would not rely on it as you are overriding what it is meant to put out and might break in the future. Let's just put out a file input with an Id and Name matching your ViewModel property.
<input type="file" name="File" Id="File/>
Next, you cannot use Ajax.BeginForm() to upload files. It is a limitation of AJAX, not an issue with the Ajax.BeginForm. So, we will need to update your form element to a normal, Html.BeginForm, with the proper enctype (this is important)
#using (Html.BeginForm("Upload", "MyControllerName", FormMethod.Post, new { enctype = "multipart/form-data"}))
{
<div id="parameterList">
<div id="verifyBtnDiv" style="display:none;">
<!-- Chose to just put the one line here instead of calling a partial-->
<input type="file" name="File" Id="File/>
<input type="submit" id="verifyBtn" value="Verify"/>
</div>
</div>
}
Lastly, if you have to/required to upload the file via AJAX, there are plenty of good recommendations on libraries to use for Ajax file uploads. I personally like the jQuery.Form plugin as it is pretty transparent in the way it handles file uploads.