#using (Html.BeginForm("Edit", "MyController", FormMethod.Post, new { enctype="multipart/form-data"}))
{
#Html.EditorFor(model => model.Name)
<input type="file" name="fileUpload" id="fileUpload" />
<input type="image" name="imb_save" src="/button_save.gif" alt="" value="Save" />
}
Submitted form and model are passed in this action:
[HttpPost]
public ActionResult Edit(MyModel mymodel, FormCollection forms)
{
if (string.IsNullOrEmpty(forms["fileUpload"]))
{
//forms["fileUpload"] does not exist
}
//TODO: something...
}
Why does not forms contain fileUpload? But it contains other inputs. How can I get content of my uploader?
Thanks.
Take a look at the following blog post for handling file uploads in ASP.NET MVC. You could use HttpPostedFileBase in your controller instead of FormCollection:
[HttpPost]
public ActionResult Edit(MyModel mymodel, HttpPostedFileBase fileUpload)
{
if (fileUpload != null && fileUpload.ContentLength > 0)
{
// The user uploaded a file => process it here
}
//TODO: something...
}
You could also make this fileUpload part of your view model:
public class MyModel
{
public HttpPostedFileBase FileUpload { get; set; }
...
}
and then:
[HttpPost]
public ActionResult Edit(MyModel mymodel)
{
if (mymodel.FileUpload != null && mymodel.FileUpload.ContentLength > 0)
{
// The user uploaded a file => process it here
}
//TODO: something...
}
Related
I have a couple of files I need to save in addition to some simple scalar data. Is there a way for me to validate that the files have been sent along with the rest of the form data? I'm trying to use the [Required] attribute, but it doesn't seem to be working.
The following worked for me.
Model:
public class MyViewModel
{
[Required]
public HttpPostedFileBase File { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new MyViewModel());
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var fileName = Path.GetFileName(model.File.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data"), fileName);
model.File.SaveAs(path);
return RedirectToAction("Index");
}
}
View:
<% using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { %>
<input type="file" name="file" />
<%= Html.ValidationMessageFor(x => x.File) %>
<input type="submit" value="OK" />
<% } %>
I'm currently using Entity Framework Code First approach for my asp.net MVC3(aspx syntax) project.
I have a model in my project called EmployeeModel
public class EmployeeModel
{
public string imageinfo;
public string fileinfo;
}
My DbContext is
public class ContextDB:DbContext
{
public DbSet<EmployeeModel> Employee { get; set; }
}
I would like to have a file browser for both fileinfo and imageinfo in my view to upload the files and images and the path of the files and images need to be stored in the database.
Can anyone please help?
Try using
.chtml
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="OK" />
}
Controller
public class HomeController : Controller
{
// This action renders the form
public ActionResult Index()
{
return View();
}
// This action handles the form POST and the upload
[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");
}
}
In Asp.Net MVC we have to use HttpPostedFileBase for Uploaded files as shown below :-
Controller :
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if (file != null) // file here will have your posted file which you post from view
{
int byteCount = file.ContentLength; <---Your file Size or Length
byte[] yourfile = new byte[file.ContentLength];
file.InputStream.Read(yourfile , 0, file.ContentLength);
var doc1 = System.Text.UnicodeEncoding.Default.GetString(empfile);
// now doc1 will have your image in string format and you can save it to database.
}
}
View :
#using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="OK" />
}
I want to give a facility on my form for user to upload files and save in Database.
How is this done in ASP.NET MVC.
What DataType to write in my Model Class. I tried with Byte[], but during the scaffolding the solution could not generate the appropriate HTML for it in the corresponding View.
How are these cases handled?
You could use a byte[] on your model and a HttpPostedFileBase on your view model. For example:
public class MyViewModel
{
[Required]
public HttpPostedFileBase File { get; set; }
}
and then:
public class HomeController: Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
byte[] uploadedFile = new byte[model.File.InputStream.Length];
model.File.InputStream.Read(uploadedFile, 0, uploadedFile.Length);
// now you could pass the byte array to your model and store wherever
// you intended to store it
return Content("Thanks for uploading the file");
}
}
and finally in your view:
#model MyViewModel
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>
#Html.LabelFor(x => x.File)
#Html.TextBoxFor(x => x.File, new { type = "file" })
#Html.ValidationMessageFor(x => x.File)
</div>
<button type="submit">Upload</button>
}
I'm trying to upload two different files into two different database fields on same form.
------------------------------------
reportid | name | image | template |
------------------------------------
this is the table look. So I want to upload files to image and template. My model:
public class Report
{
[Key]
public int ReportID { get; set; }
[Required]
public string Name { get; set; }
public byte[] Image { get; set; }
public byte[] Template { get; set; }
}
My Create method in controller:
public ActionResult Create(Report report, HttpPostedFileBase file, HttpPostedFileBase temp)
{
if (ModelState.IsValid)
{
if (file != null && file.ContentLength > 0)
{
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
report.Image = ms.GetBuffer();
}
}
if (temp != null && temp.ContentLength > 0)
{
using (MemoryStream ms1 = new MemoryStream())
{
temp.InputStream.CopyTo(ms1);
report.Template = ms1.GetBuffer();
}
}
db.Reports.Add(report);
db.SaveChanges();
db.Configuration.ValidateOnSaveEnabled = true;
return RedirectToAction("Index");
}
And part of view concerning uploads:
<div class="editor-label">
<%:Html.LabelFor(model => model.Image) %>
</div>
<div class="editor-field">
<input type="file" id="fuImage" name="file" />
</div>
<div class="editor-label">
<%:Html.Label("Template") %>
</div>
<div class="editor-field">
<input type="file" id="temp" name="temp"/>
</div>
<p>
<input type="submit" value="Create" />
</p>
I'm quite stuck in this since I can not use IEnumerable<HttpPostedFileBase> files as a parameter in Create method because I need to save it in a different field, or can I? How should I approach this? Please help :S
Note: Image upload works fine.
Why not use IEnumerable<HttpPostedFileBase> ? You may use it like this.
[HttpPost]
public ActionResult Create(Report report, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
//Let's take first file
if(files.ElementAt(0)!=null)
{
var file1=files.ElementAt(0);
if (file1!= null && file1.ContentLength > 0)
{
//do processing of first file
}
}
//Let's take the second one now.
if(files.ElementAt(1)!=null)
{
var temp =files.ElementAt(1);
if (temp!= null && temp.ContentLength > 0)
{
//do processing of second file here
}
}
}
//Do your code for saving the data.
return RedirectToAction("Index");
}
EDIT : After seeing your View Markup in your EDIT.
The name of the file input element should be same as the parameter name in your action method. (files in this example)
#using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<b>File 1</b>
<input type="file" name="files" id="file1" />
<b>File 2</b>
<input type="file" name="files" id="file2" />
<input type="submit" />
}
This code assumes that read ONLY the first 2 entries from the collection.Since you wanted only 2 files, i hardcoded the indexes.
Phil has a nice blog post explaining about it very nicely.
HI there,
My model (partial)
public class Document : HttpPostedFileBase
{
public string DocumentTitle { get; set; }
public string DocumentType { get; set; }
My action
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddDocumentToVault(Document model)
{
foreach (string upload in Request.Files)
{
if (!Request.Files[upload].HasFile()) continue;
_documentAggregator.Add(model);
_documentAggregator.Commit();
}
return PSDocumentVaultPartial();
}
File uploader
<% using (Html.BeginForm("AddDocumentToVault", "PersonalSpace", FormMethod.Post, new { enctype = "multipart/form-data" }))
{%>
<input type="file" id="Document" runat="server" name="Document"/>
<input id="AddDocument" type="submit" value="Upload" style="display:none"/>
<% } %>
The problem I am having is that when the AddDocument button is pressed it's passing an empty model to the action in my controller. And the base properties in HttpPostedFileBase give a System.NotImplementException.
Can anyone tell me what I need to do to correctly pass my model to my action?
It's an issue with HttpPostedFileBase and model binding. See ASP.NET MVC posted file model binding when parameter is Model