I have actually done similar in a recent project.
In your view you can create an input tag of type file, which it looks like you have already done.
<input name="attachment" type="file">
Then in your controller, you can use the HttpPostedFileBase class to to pass it back to your code and save it.
[HttpPost]
public ActionResult Save(HttpPostedFileBase Attachment)
{
//do stuff
SaveFile(Attachment)
}
This method returns an enum which I will attach later on. I use an enum here in a similar effect to boolean except I can return more than two options.
public FileUploadState SaveFile(HttpPostedFileBase Attachment)
{
if(Attachment != null)
{
try //attempt to save file to file system
{
var fileName = Path.GetFileName(Attachment.FileName);
//path as parameter can be changed to any desired valid path
var path = Path.Combine((@"C:\Images"), fileName);
Attachment.SaveAs(path);
return FileUploadState.Uploaded;
}
catch //implement your own error handling here
{
//error handling
return FileUploadState.Failed;
}
}
else
{
return FileUploadState.NoFileSelected;
}
}
Enum: In computer programming, an enumerated type is a data type consisting of a set of named values called elements, members, enumeral, or enumerators of the type. More info on Enums
public enum fileUploadState
{
Uploaded,
NoFileSelected,
Failed
}
Then to access these attachments, later on you can put this code in. Assuming you are reading filenames from a database.
In your controller:
readFileName = get filename from DB;
ViewBag.Attachment = readFileName;
In your view create a link for your user to click to open the attachment: target = "_blank" opens in a new tab
@Html.ActionLink("First Attachment: " + (string)ViewBag.Attachment, "DownloadAttachment", new { @FileName = (string)ViewBag.Attachment }, new { target = "_blank" })}
Back to your controller: Assuming you use the same Attachment class I created. I created the attachment class with a valid constructor to store useful information about the files, i.e. filenames, paths (incase different), byte content.
public ActionResult DownloadAttachment(string FileName)
{
//path as parameter can be changed to wherever the file exists
Attachment attach = new Attachment(FileName, @"C:\Images");
//when attachment is created, byte content is read
var cd = new System.Net.Mime.ContentDisposition
{
FileName = attach.FileName,
Inline = true,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
//return content
return File(attach.FileData, attach1.contentType);
}
Attachment Class:
public class Attachment
{
public string FileName { get; set; }
public string FilePath { get; set; }
public byte[] FileData { get; set; }
public string contentType { get; set; }
public Attachment(string fileName, string filePath)
{
this.FileName = fileName;
this.FilePath = filePath + @"\"+ fileName ;
this.FileData = System.IO.File.ReadAllBytes(FilePath);
this.contentType = MimeMapping.GetMimeMapping(FilePath);
}
}
@Html.TextBoxFor(model => model.Picture, new { type = "file" })to generate the html (wherePictureis typeofHttpPostedFileBasein your view model) and you need to add theenctype = "multipart/form-data"attribute to the form