ASP.NET MVC 4 C# Httppostedfilebase, How to Store File

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).
Sample Image

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



Leave a reply



Submit