ASP.NET MVC 4 C# HttpPostedFileBase, How do I Store File
you can upload file and save its url in the database table like this:
View:
@using(Html.BeginForm("Create","Assignment",FormMethod.Post,new {enctype="multipart/form-data"}))
{
...
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FileLocation, new { type="file"})%>
<%: Html.ValidationMessageFor(model => model.FileLocation) %>
</div>
...
}
Action:
[HttpPost]
public ActionResult Create(Assignment assignment)
{
if (ModelState.IsValid)
{
if(Request.Files.Count > 0)
{
HttpPostedFileBase file = Request.Files[0];
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
assignment.FileLocation = Path.Combine(
Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(assignment.FileLocation);
}
db.Assignments.Add(assignment);
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(assignment);
}
Details:
For better understanding refer this good article Uploading a File (Or Files) With ASP.NET MVC
C# MVC 4 ASP.net, How to Insert File into Database store in (binary)
You need a bit more processing here. Uploaded files come in as a HttpPostedFileBase
, not a byte[]
so you need to get the byte[]
from the HttpPostedFileBase's InputStream, like so:
[HttpPost]
public ActionResult Create(Assignment assignment)
{
if(Request.Files != null && Request.Files.Count == 1)
{
var file = Request.Files[0];
if (file != null && file.ContentLength > 0)
{
var content = new byte[file.ContentLength];
file.InputStream.Read(content, 0, file.ContentLength);
assignment.FileLocation = content;
// the rest of your db code here
}
}
return RedirectToAction("Create");
}
P.S. That model looks suspiciously like an Entity object. It's a tremendously bad idea to use Entity objects as your models. Try making an intermediary model and using that to render your data instead.
Edit
In your view, change this:
<%: Html.TextBoxFor(model => model.FileLocation, new { type="file"})%>
to this:
<input type="file" id="file" name="file" />
The error you're getting is because the model binder is mistakenly trying to bind your FileLocation field on the page (HttpPostedFileBase type) to the FileLocation field in your model (byte[] type).
HttpPostedFileBase Null in controller - Want to save file path to database
It is recommended to add the file to your model:
public class Report {
[Required]
[Display(Name = "Report File")]
public HttpPostedFileBase ReportFile { get; set; }
//... The other fields
}
Usually I would append ViewModel
, so ReportViewModel
instead of Report
. This makes it easier to distinguish between view models and business/data models.
And in your Razor:
<div class="form-group">
@Html.LabelFor(m => m.Report.ReportFile)
@Html.TextBoxFor(m => m.ReportFile, new { type = "file" })
<!--You can also use <input type="file" name="ReportFile" id="ReportFile"/>-->
</div>
Note that the name that you use in the LabelFor
must match the ID of the control. In your code FilePath
and file
didn't match.
And finally in the controller:
public ActionResult Save(Report report)
{
//...some code
string filePath = Path.Combine(Server.MapPath("~/App_Data/Uploads"),
Path.GetFileName(report.ReportFile.FileName));
report.ReportFile.SaveAs(filePath);
//...other code
}
I wouldn't use the name of the uploaded file. Instead, I would give it a name according to my project's naming convention. I often use the ID as the name, perhaps with some prefix. Example:
var fileName = "F" + report.Id + ".jpg"; //You can get the extension from the uploaded file
string filePath = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName);
Obviously, when you're inserting a new object, you won't have an ID until you insert it into the database, so the code to save the physical file must be placed after the code to insert it into the database. If you follow this logic, you don't need to save the path in the database, because the path can be always calculated from the ID. So you save a column in the database, gain performance in your code as you don't need to handle another string column, and you have a clear and simply file naming convention that is safe without user input risk.
Another way I follow, especially when the type of the file may vary (i.e. you can upload files with different extensions), is using a GUID for the file name. In this case, the file name must be saved in the database, but the GUID can be generated before inserting the object into the database. Example:
string ext = report.ReportFile.FileName.Substring(
report.ReportFile.FileName.LastIndexOf('.')).ToLower();
var fileName = Guid.NewGuid().ToString() + ext;
string filePath = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName);
ASP.NET MVC 4 C# HttpPostedFileBase, EntityValidationErrors Save into DB
Does it mention which column would have the data truncated? The data you're trying to save into that column is too long, that is, longer than the defined maximum length.
HttpPostedFileBase in model generates three input type=file
As far as I know in MVC 4, EditorFor
helper doesn't support htmlAttributes
yet (this object
parameter is available for MVC 5.1 or above), usually the file input from HttpPostedFileBase
property is generated by using TextBoxFor
helper:
@Html.TextBoxFor(m => m.file, new { type = "file" })
Note:
While trying to use htmlAttributes
inside EditorFor
, I found that the helper generates other 3 inputs, each named ContentLength
, ContentType
and FileName
, hence I suspected the helper created inputs from several public property members of HttpPostedFileBase
class instead of the property itself.
How to Retain HttpPostedFileBase on View Return
I have two solution for your problem:
Remote Validation:
according to following sentence "I have a server side validation for the Content textbox", in my view you can use remote validation for validate your form instead send your form to server.This link can help you to using Remote Validation(I would recommend this).
Temporary Store
In this solution you must use ajax-enabled file-upload component (such as this) to send file or files to server. Then you must prepare a action in order to receive file and save it in temporary storage such as (cache or file system) and generate a file-reference to restore the saved file and finally return the file-reference to client.The client insert received file-reference to form as a hidden input thus from then each time form sent, send file-reference instead file content.Of course two points should be noted:
1) Prepare a action to cancel a selected file with user request
2) Prepare a api for restore temporary file by file reference
3) Manage the temporary files to make sure that those don't fill your storage(if using asp.net cache as temporary storage the IIS itself handle it).
public ActionResult UploadTemporary(HttpPostedFileBase file)
{
Guid reference = Guid.NewGuid();
string extension = Path.GetExtension(file.FileName);
string fullName= reference.ToString()+extension;
var path = Path.Combine(Server.MapPath("~/Content/TempFiles/"), fullName);
var data = new byte[file.ContentLength];
file.InputStream.Read(data, 0, file.ContentLength);
using (var sw = new FileStream(path, FileMode.Create))
{
sw.Write(data, 0, data.Length);
}
return Content(reference);
}
summary
The first solution is quick and easy if you encounter with a few of this requirement case in your project, but if you encounter with a lot number of this case I recommend you to use second solution.The second solution is so time-consuming but very useful for applications that lots deal with file.
How to create input type file for HttpPostedFileBase in edit page ASP.NET MVC?
You simply cannot use HttpPostedFileBase
to display your files.
As its description says:
Serves as the base class for classes that provide access to individual files that have been uploaded by a client.
It is used to access files that are being uploaded. If you want to display files that have been uploaded, then you have to use some other approach like using File methods.
Related Topics
Garbage Collection When Using Anonymous Delegates for Event Handling
Redirecting Output to the Text File C#
Reading from a Text File in C#
Why \B Does Not Match Word Using .Net Regex
Send Email via C# Through Google Apps Account
Sending and Receiving Data Over a Network Using Tcpclient
Casting VS Converting an Object Tostring, When Object Really Is a String
ASP.NET MVC 4 C# Httppostedfilebase, How to Store File
Which Blocking Operations Cause an Sta Thread to Pump Com Messages
Wait for a While Without Blocking Main Thread
Groupby on Complex Object (E.G. List<T>)
How to Create a Button That Can Send Keys to a Conrol Without Losing Focus - Virtual Keyboard
C# Passing Function as Argument