file uploadASP.NET MVC 3.0
我想在asp.net-mvc上传文件。 如何使用html input file
控件上传input file
?
您不使用文件input控件。 ASP.NET MVC中不使用服务器端控件。 检出以下博客文章 ,说明如何在ASP.NET MVC中实现此function。
所以你可以从创build一个包含文件input的HTML表单开始:
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { <input type="file" name="file" /> <input type="submit" value="OK" /> }
然后你将有一个控制器来处理上传:
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 filename 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"); } }
转移到byte[]
(例如保存到DB):
using (MemoryStream ms = new MemoryStream()) { file.InputStream.CopyTo(ms); byte[] array = ms.GetBuffer(); }
要将inputstream直接传输到数据库中,而不将其存储在内存中,则可以使用从此处获取的此类并稍微更改一下:
public class VarbinaryStream : Stream { private SqlConnection _Connection; private string _TableName; private string _BinaryColumn; private string _KeyColumn; private int _KeyValue; private long _Offset; private SqlDataReader _SQLReader; private long _SQLReadPosition; private bool _AllowedToRead = false; public VarbinaryStream( string ConnectionString, string TableName, string BinaryColumn, string KeyColumn, int KeyValue, bool AllowRead = false) { // create own connection with the connection string. _Connection = new SqlConnection(ConnectionString); _TableName = TableName; _BinaryColumn = BinaryColumn; _KeyColumn = KeyColumn; _KeyValue = KeyValue; // only query the database for a result if we are going to be reading, otherwise skip. _AllowedToRead = AllowRead; if (_AllowedToRead == true) { try { if (_Connection.State != ConnectionState.Open) _Connection.Open(); SqlCommand cmd = new SqlCommand( @"SELECT TOP 1 [" + _BinaryColumn + @"] FROM [dbo].[" + _TableName + @"] WHERE [" + _KeyColumn + "] = @id", _Connection); cmd.Parameters.Add(new SqlParameter("@id", _KeyValue)); _SQLReader = cmd.ExecuteReader( CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow | CommandBehavior.CloseConnection); _SQLReader.Read(); } catch (Exception e) { // log errors here } } } // this method will be called as part of the Stream ímplementation when we try to write to our VarbinaryStream class. public override void Write(byte[] buffer, int index, int count) { try { if (_Connection.State != ConnectionState.Open) _Connection.Open(); if (_Offset == 0) { // for the first write we just send the bytes to the Column SqlCommand cmd = new SqlCommand( @"UPDATE [dbo].[" + _TableName + @"] SET [" + _BinaryColumn + @"] = @firstchunk WHERE [" + _KeyColumn + "] = @id", _Connection); cmd.Parameters.Add(new SqlParameter("@firstchunk", buffer)); cmd.Parameters.Add(new SqlParameter("@id", _KeyValue)); cmd.ExecuteNonQuery(); _Offset = count; } else { // for all updates after the first one we use the TSQL command .WRITE() to append the data in the database SqlCommand cmd = new SqlCommand( @"UPDATE [dbo].[" + _TableName + @"] SET [" + _BinaryColumn + @"].WRITE(@chunk, NULL, @length) WHERE [" + _KeyColumn + "] = @id", _Connection); cmd.Parameters.Add(new SqlParameter("@chunk", buffer)); cmd.Parameters.Add(new SqlParameter("@length", count)); cmd.Parameters.Add(new SqlParameter("@id", _KeyValue)); cmd.ExecuteNonQuery(); _Offset += count; } } catch (Exception e) { // log errors here } } // this method will be called as part of the Stream ímplementation when we try to read from our VarbinaryStream class. public override int Read(byte[] buffer, int offset, int count) { try { long bytesRead = _SQLReader.GetBytes(0, _SQLReadPosition, buffer, offset, count); _SQLReadPosition += bytesRead; return (int)bytesRead; } catch (Exception e) { // log errors here } return -1; } public override bool CanRead { get { return _AllowedToRead; } } protected override void Dispose(bool disposing) { if (_Connection != null) { if (_Connection.State != ConnectionState.Closed) try { _Connection.Close(); } catch { } _Connection.Dispose(); } base.Dispose(disposing); } #region unimplemented methods public override bool CanSeek { get { return false; } } public override bool CanWrite { get { return true; } } public override void Flush() { throw new NotImplementedException(); } public override long Length { get { throw new NotImplementedException(); } } public override long Position { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public override long Seek(long offset, SeekOrigin origin) { throw new NotImplementedException(); } public override void SetLength(long value) { throw new NotImplementedException(); } #endregion unimplemented methods }
和用法:
using (var filestream = new VarbinaryStream( "Connection_String", "Table_Name", "Varbinary_Column_name", "Key_Column_Name", keyValueId, true)) { postedFile.InputStream.CopyTo(filestream); }
另一种方法转移到字节[](保存到数据库)。
@Arthur的方法工作的很好,但不能完美复制,所以MS Office文档在从数据库中检索后可能无法打开。 MemoryStream.GetBuffer()可以在byte []的末尾返回多余的空字节,但是可以使用MemoryStream.ToArray()来修复。 但是,我发现这个替代scheme可以完美地适用于所有文件types:
using (var binaryReader = new BinaryReader(file.InputStream)) { byte[] array = binaryReader.ReadBytes(file.ContentLength); }
这是我的完整代码:
文件类别:
public class Document { public int? DocumentID { get; set; } public string FileName { get; set; } public byte[] Data { get; set; } public string ContentType { get; set; } public int? ContentLength { get; set; } public Document() { DocumentID = 0; FileName = "New File"; Data = new byte[] { }; ContentType = ""; ContentLength = 0; } }
文件下载:
[HttpGet] public ActionResult GetDocument(int? documentID) { // Get document from database var doc = dataLayer.GetDocument(documentID); // Convert to ContentDisposition var cd = new System.Net.Mime.ContentDisposition { FileName = doc.FileName, // Prompt the user for downloading; set to true if you want // the browser to try to show the file 'inline' (display in-browser // without prompting to download file). Set to false if you // want to always prompt them to download the file. Inline = true, }; Response.AppendHeader("Content-Disposition", cd.ToString()); // View document return File(doc.Data, doc.ContentType); }
上传文件:
[HttpPost] public ActionResult GetDocument(HttpPostedFileBase file) { // Verify that the user selected a file if (file != null && file.ContentLength > 0) { // Get file info var fileName = Path.GetFileName(file.FileName); var contentLength = file.ContentLength; var contentType = file.ContentType; // Get file data byte[] data = new byte[] { }; using (var binaryReader = new BinaryReader(file.InputStream)) { data = binaryReader.ReadBytes(file.ContentLength); } // Save to database Document doc = new Document() { FileName = fileName, Data = data, ContentType = contentType, ContentLength = contentLength, }; dataLayer.SaveDocument(doc); // Show success ... return RedirectToAction("Index"); } else { // Show error ... return View("Foo"); } }
查看(snippet):
@using (Html.BeginForm("GetDocument", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { <input type="file" name="file" /> <input type="submit" value="Upload File" /> }
通常你也想传递一个viewmodel,而不是唯一的一个文件。 在下面的代码中,你会发现一些其他有用的function:
- 检查文件是否已附加
- 检查文件大小是否为0
- 检查文件大小是否高于4 MB
- 检查文件大小是否小于100字节
- 检查文件扩展名
可以通过以下代码完成:
[HttpPost] public ActionResult Index(MyViewModel viewModel) { // if file's content length is zero or no files submitted if (Request.Files.Count != 1 || Request.Files[0].ContentLength == 0) { ModelState.AddModelError("uploadError", "File's length is zero, or no files found"); return View(viewModel); } // check the file size (max 4 Mb) if (Request.Files[0].ContentLength > 1024 * 1024 * 4) { ModelState.AddModelError("uploadError", "File size can't exceed 4 MB"); return View(viewModel); } // check the file size (min 100 bytes) if (Request.Files[0].ContentLength < 100) { ModelState.AddModelError("uploadError", "File size is too small"); return View(viewModel); } // check file extension string extension = Path.GetExtension(Request.Files[0].FileName).ToLower(); if (extension != ".pdf" && extension != ".doc" && extension != ".docx" && extension != ".rtf" && extension != ".txt") { ModelState.AddModelError("uploadError", "Supported file extensions: pdf, doc, docx, rtf, txt"); return View(viewModel); } // extract only the filename var fileName = Path.GetFileName(Request.Files[0].FileName); // store the file inside ~/App_Data/uploads folder var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName); try { if (System.IO.File.Exists(path)) System.IO.File.Delete(path); Request.Files[0].SaveAs(path); } catch (Exception) { ModelState.AddModelError("uploadError", "Can't save file to disk"); } if(ModelState.IsValid) { // put your logic here return View("Success"); } return View(viewModel); }
确保你有
@Html.ValidationMessage("uploadError")
在您的视图中validation错误。
另外请记住,默认的最大请求长度是4MB(maxRequestLength = 4096),要上传更大的文件,您必须在web.config中更改此参数:
<system.web> <httpRuntime maxRequestLength="40960" executionTimeout="1100" />
(40960 = 40 MB在这里)。
执行超时是整个秒数。 您可能想要更改它以允许上传大文件。
在看法:
<form action="Categories/Upload" enctype="multipart/form-data" method="post"> <input type="file" name="Image"> <input type="submit" value="Save"> </form>
而在控制器中的以下代码:
public ActionResult Upload() { foreach (string file in Request.Files) { var hpf = this.Request.Files[file]; if (hpf.ContentLength == 0) { continue; } string savedFileName = Path.Combine( AppDomain.CurrentDomain.BaseDirectory, "PutYourUploadDirectoryHere"); savedFileName = Path.Combine(savedFileName, Path.GetFileName(hpf.FileName)); hpf.SaveAs(savedFileName); } ... }
我必须使用命令将file upload到100 kb的文件块和最后的上传文件存储区。 我希望,这将有助于你。
public HttpResponseMessage Post(AttachmentUploadForm form) { var response = new WebApiResultResponse { IsSuccess = true, RedirectRequired = false }; var tempFilesFolder = Sanelib.Common.SystemSettings.Globals.CreateOrGetCustomPath("Temp\\" + form.FileId); File.WriteAllText(tempFilesFolder + "\\" + form.ChunkNumber + ".temp", form.ChunkData); if (form.ChunkNumber < Math.Ceiling((double)form.Size / 102400)) return Content(response); var folderInfo = new DirectoryInfo(tempFilesFolder); var totalFiles = folderInfo.GetFiles().Length; var sb = new StringBuilder(); for (var i = 1; i <= totalFiles; i++) { sb.Append(File.ReadAllText(tempFilesFolder + "\\" + i + ".temp")); } var base64 = sb.ToString(); base64 = base64.Substring(base64.IndexOf(',') + 1); var fileBytes = Convert.FromBase64String(base64); var fileStream = new FileStream(tempFilesFolder + "\\" + form.Name, FileMode.OpenOrCreate, FileAccess.ReadWrite); fileStream.Seek(fileStream.Length, SeekOrigin.Begin); fileStream.Write(fileBytes, 0, fileBytes.Length); fileStream.Close(); Directory.Delete(tempFilesFolder, true); var md5 = MD5.Create(); var command = Mapper.Map<AttachmentUploadForm, AddAttachment>(form); command.FileData = fileBytes; command.FileHashCode = BitConverter.ToString(md5.ComputeHash(fileBytes)).Replace("-", ""); return ExecuteCommand(command); }
Javascript(Knockout Js)
define(['util', 'ajax'], function (util, ajax) { "use strict"; var exports = {}, ViewModel, Attachment, FileObject; //File Upload FileObject = function (file, parent) { var self = this; self.fileId = util.guid(); self.name = ko.observable(file.name); self.type = ko.observable(file.type); self.size = ko.observable(); self.fileData = null; self.fileSize = ko.observable(file.size / 1024 / 1024); self.chunks = 0; self.currentChunk = ko.observable(); var reader = new FileReader(); // Closure to capture the file information. reader.onload = (function (e) { self.fileData = e.target.result; self.size(self.fileData.length); self.chunks = Math.ceil(self.size() / 102400); self.sendChunk(1); }); reader.readAsDataURL(file); self.percentComplete = ko.computed(function () { return self.currentChunk() * 100 / self.chunks; }, self); self.cancel = function (record) { parent.uploads.remove(record); }; self.sendChunk = function (number) { var start = (number - 1) * 102400; var end = number * 102400; self.currentChunk(number); var form = { fileId: self.fileId, name: self.name(), fileType: self.type(), Size: self.size(), FileSize: self.fileSize(), chunkNumber: number, chunkData: self.fileData.slice(start, end), entityTypeValue: parent.entityTypeValue, ReferenceId: parent.detail.id, ReferenceName: parent.detail.name }; ajax.post('Attachment', JSON.stringify(form)).done(function (response) { if (number < self.chunks) self.sendChunk(number + 1); if (response.id != null) { parent.attachments.push(new Attachment(response)); self.cancel(response); } }); }; }; Attachment = function (data) { var self = this; self.id = ko.observable(data.id); self.name = ko.observable(data.name); self.fileType = ko.observable(data.fileType); self.fileSize = ko.observable(data.fileSize); self.fileData = ko.observable(data.fileData); self.typeName = ko.observable(data.typeName); self.description = ko.observable(data.description).revertable(); self.tags = ko.observable(data.tags).revertable(); self.operationTime = ko.observable(moment(data.createdOn).format('MM-DD-YYYY HH:mm:ss')); self.description.subscribe(function () { var form = { Id: self.id(), Description: self.description(), Tags: self.tags() }; ajax.put('attachment', JSON.stringify(form)).done(function (response) { self.description.commit(); return; }).fail(function () { self.description.revert(); }); }); self.tags.subscribe(function () { var form = { Id: self.id(), Description: self.description(), Tags: self.tags() }; ajax.put('attachment', JSON.stringify(form)).done(function (response) { self.tags.commit(); return; }).fail(function () { self.tags.revert(); }); }); }; ViewModel = function (data) { var self = this; // for attachment self.attachments = ko.observableArray([]); $.each(data.attachments, function (row, val) { self.attachments.push(new Attachment(val)); }); self.deleteAttachmentRecord = function (record) { if (!confirm("Are you sure you want to delete this record?")) return; ajax.del('attachment', record.id(), { async: false }).done(function () { self.attachments.remove(record); return; }); }; exports.exec = function (model) { console.log(model); var viewModel = new ViewModel(model); ko.applyBindings(viewModel, document.getElementById('ShowAuditDiv')); }; return exports; });
HTML代码:
<div class="row-fluid spacer-bottom fileDragHolder"> <div class="spacer-bottom"></div> <div class="legend"> Attachments<div class="pull-right">@Html.AttachmentPicker("AC")</div> </div> <div> <div class="row-fluid spacer-bottom"> <div style="overflow: auto"> <table class="table table-bordered table-hover table-condensed" data-bind="visible: uploads().length > 0 || attachments().length > 0"> <thead> <tr> <th class=" btn btn-primary col-md-2" style="text-align: center"> Name </th> <th class="btn btn-primary col-md-1" style="text-align: center">Type</th> <th class="btn btn-primary col-md-1" style="text-align: center">Size (MB)</th> <th class="btn btn-primary col-md-1" style="text-align: center">Upload Time</th> <th class="btn btn-primary col-md-1" style="text-align: center">Tags</th> <th class="btn btn-primary col-md-6" style="text-align: center">Description</th> <th class="btn btn-primary col-md-1" style="text-align: center">Delete</th> </tr> </thead> <tbody> <!-- ko foreach: attachments --> <tr> <td style="text-align: center" class="col-xs-2"><a href="#" data-bind="text: name,attr:{'href':'/attachment/index?id=' + id()}"></a></td> <td style="text-align: center" class="col-xs-1"><span data-bind="text: fileType"></span></td> <td style="text-align: center" class="col-xs-1"><span data-bind="text: fileSize"></span></td> <td style="text-align: center" class="col-xs-2"><span data-bind="text: operationTime"></span></td> <td style="text-align: center" class="col-xs-3"><div contenteditable="true" data-bind="editableText: tags"></div></td> <td style="text-align: center" class="col-xs-4"><div contenteditable="true" data-bind="editableText: description"></div></td> <td style="text-align: center" class="col-xs-1"><button class="btn btn-primary" data-bind="click:$root.deleteAttachmentRecord"><i class="icon-trash"></i></button></td> </tr> <!-- /ko --> </tbody> <tfoot data-bind="visible: uploads().length > 0"> <tr> <th colspan="6">Files upload status</th> </tr> <tr> <th>Name</th> <th>Type</th> <th>Size (MB)</th> <th colspan="2">Status</th> <th></th> </tr> <!-- ko foreach: uploads --> <tr> <td><span data-bind="text: name"></span></td> <td><span data-bind="text: type"></span></td> <td><span data-bind="text: fileSize"></span></td> <td colspan="2"> <div class="progress"> <div class="progress-bar" data-bind="style: { width: percentComplete() + '%' }"></div> </div> </td> <td style="text-align: center"><button class="btn btn-primary" data-bind="click:cancel"><i class="icon-trash"></i></button></td> </tr> <!-- /ko --> </tfoot> </table> </div> <div data-bind="visible: attachments().length == 0" class="span12" style="margin-left:0"> <span>No Records found.</span> </div> </div>
我如何做我的是非常像上面生病向您展示我的代码,以及如何使用它与MYSSQL DB …
DB中的文档表 –
int Id(PK),stringUrl,string描述,CreatedBy,TenancyId DateUploaded
上面的代码ID是主键,URL是文件的名称(文件types在最后),输出到文档视图上的文件描述,CreatedBy是谁上传文件,tenancyId,dateUploaded
在视图里面你必须定义enctype或者它不能正常工作。
@using (Html.BeginForm("Upload", "Document", FormMethod.Post, new { enctype = "multipart/form-data" })) { <div class="input-group"> <label for="file">Upload a document:</label> <input type="file" name="file" id="file" /> </div> }
上面的代码会给你浏览button,然后在我的项目里面,我有一个基本上称为IsValidImage的类,它只是检查文件大小是否在你指定的最大大小,检查它是否是一个IMG文件,这是所有类bool函数。 所以如果真的返回true。
public static bool IsValidImage(HttpPostedFileBase file, double maxFileSize, ModelState ms ) { // make sur the file isnt null. if( file == null ) return false; // the param I normally set maxFileSize is 10MB 10 * 1024 * 1024 = 10485760 bytes converted is 10mb var max = maxFileSize * 1024 * 1024; // check if the filesize is above our defined MAX size. if( file.ContentLength > max ) return false; try { // define our allowed image formats var allowedFormats = new[] { ImageFormat.Jpeg, ImageFormat.Png, ImageFormat.Gif, ImageFormat.Bmp }; // Creates an Image from the specified data stream. using (var img = Image.FromStream(file.InputStream)) { // Return true if the image format is allowed return allowedFormats.Contains(img.RawFormat); } } catch( Exception ex ) { ms.AddModelError( "", ex.Message ); } return false; }
所以在控制器中:
if (!Code.Picture.IsValidUpload(model.File, 10, true)) { return View(model); } // Set the file name up... Being random guid, and then todays time in ticks. Then add the file extension // to the end of the file name var dbPath = Guid.NewGuid().ToString() + DateTime.UtcNow.Ticks + Path.GetExtension(model.File.FileName); // Combine the two paths together being the location on the server to store it // then the actual file name and extension. var path = Path.Combine(Server.MapPath("~/Uploads/Documents/"), dbPath); // set variable as Parent directory I do this to make sure the path exists if not // I will create the directory. var directoryInfo = new FileInfo(path).Directory; if (directoryInfo != null) directoryInfo.Create(); // save the document in the combined path. model.File.SaveAs(path); // then add the data to the database _db.Documents.Add(new Document { TenancyId = model.SelectedTenancy, FileUrl = dbPath, FileDescription = model.Description, CreatedBy = loggedInAs, CreatedDate = DateTime.UtcNow, UpdatedDate = null, CanTenantView = true }); _db.SaveChanges(); model.Successfull = true;
public ActionResult FileUpload(upload mRegister) { //Check server side validation using data annotation if (ModelState.IsValid) { //TO:DO var fileName = Path.GetFileName(mRegister.file.FileName); var path = Path.Combine(Server.MapPath("~/Content/Upload"), fileName); mRegister.file.SaveAs(path); ViewBag.Message = "File has been uploaded successfully"; ModelState.Clear(); } return View(); }
提供完整的解决scheme
首先使用MVC视图中的.CShtmlinput
<input type="file" id="UploadImg" /></br> <img id="imgPreview" height="200" width="200" />
现在调用Ajax调用
$("#UploadImg").change(function () { var data = new FormData(); var files = $("#UploadImg").get(0).files; if (files.length > 0) { data.append("MyImages", files[0]); } $.ajax({ // url: "Controller/ActionMethod" url: "/SignUp/UploadFile", type: "POST", processData: false, contentType: false, data: data, success: function (response) { //code after success $("#UploadPhoto").val(response); $("#imgPreview").attr('src', '/Upload/' + response); }, error: function (er) { //alert(er); } }); });
控制器Json呼叫
[HttpGet] public JsonResult UploadFile() { string _imgname = string.Empty; if (System.Web.HttpContext.Current.Request.Files.AllKeys.Any()) { var pic = System.Web.HttpContext.Current.Request.Files["MyImages"]; if (pic.ContentLength > 0) { var fileName = Path.GetFileName(pic.FileName); var _ext = Path.GetExtension(pic.FileName); _imgname = Guid.NewGuid().ToString(); var _comPath = Server.MapPath("/MyFolder") + _imgname + _ext; _imgname = "img_" + _imgname + _ext; ViewBag.Msg = _comPath; var path = _comPath; tblAssignment assign = new tblAssignment(); assign.Uploaded_Path = "/MyFolder" + _imgname + _ext; // Saving Image in Original Mode pic.SaveAs(path); } } return Json(Convert.ToString(_imgname), JsonRequestBehavior.AllowGet); }
我给你简单易懂的方法来了解和学习。
首先,您必须在.Cshtml文件中编写以下代码。
<input name="Image" type="file" class="form-control" id="resume" />
然后在你的控制器中input以下代码:
if (i > 0) { HttpPostedFileBase file = Request.Files["Image"]; if (file != null && file.ContentLength > 0) { if (!string.IsNullOrEmpty(file.FileName)) { string extension = Path.GetExtension(file.FileName); switch ((extension.ToLower())) { case ".doc": break; case ".docx": break; case ".pdf": break; default: ViewBag.result = "Please attach file with extension .doc , .docx , .pdf"; return View(); } if (!Directory.Exists(Server.MapPath("~") + "\\Resume\\")) { System.IO.Directory.CreateDirectory(Server.MapPath("~") + "\\Resume\\"); } string documentpath = Server.MapPath("~") + "\\Resume\\" + i + "_" + file.FileName; file.SaveAs(documentpath); string filename = i + "_" + file.FileName; result = _objbalResume.UpdateResume(filename, i); Attachment at = new Attachment(documentpath); //ViewBag.result = (ans == true ? "Thanks for contacting us.We will reply as soon as possible" : "There is some problem. Please try again later."); } } else { ... } }
为此,您必须根据您的数据库制作BAL和DAL图层。
这是我的工作示例:
[HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> Create(Product product, HttpPostedFileBase file) { if (!ModelState.IsValid) return PartialView("Create", product); if (file != null) { var fileName = Path.GetFileName(file.FileName); var guid = Guid.NewGuid().ToString(); var path = Path.Combine(Server.MapPath("~/Content/Uploads/ProductImages"), guid + fileName); file.SaveAs(path); string fl = path.Substring(path.LastIndexOf("\\")); string[] split = fl.Split('\\'); string newpath = split[1]; string imagepath = "Content/Uploads/ProductImages/" + newpath; using (MemoryStream ms = new MemoryStream()) { file.InputStream.CopyTo(ms); byte[] array = ms.GetBuffer(); } var nId = Guid.NewGuid().ToString(); // Save record to database product.Id = nId; product.State = 1; product.ImagePath = imagepath; product.CreatedAt = DateTime.Now; db.Products.Add(product); await db.SaveChangesAsync(); TempData["message"] = "ProductCreated"; //return RedirectToAction("Index", product); } // after successfully uploading redirect the user return Json(new { success = true }); }
请注意只有上传图片的代码。 我使用HTMLHelper上传图片。 在cshtml文件中放这个代码
@using (Html.BeginForm("UploadImageAction", "Admin", FormMethod.Post, new { enctype = "multipart/form-data", id = "myUploadForm" })) { <div class="controls"> @Html.UploadFile("UploadImage") </div> <button class="button">Upload Image</button> }
然后创build一个HTMLHelper上传标签
public static class UploadHelper { public static MvcHtmlString UploadFile(this HtmlHelper helper, string name, object htmlAttributes = null) { TagBuilder input = new TagBuilder("input"); input.Attributes.Add("type", "file"); input.Attributes.Add("id", helper.ViewData.TemplateInfo.GetFullHtmlFieldId(name)); input.Attributes.Add("name", helper.ViewData.TemplateInfo.GetFullHtmlFieldName(name)); if (htmlAttributes != null) { var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); input.MergeAttributes(attributes); } return new MvcHtmlString(input.ToString()); } }
最后在操作上传你的文件
[AjaxOnly] [HttpPost] public ActionResult UploadImageAction(HttpPostedFileBase UploadImage) { string path = Server.MapPath("~") + "Files\\UploadImages\\" + UploadImage.FileName; System.Drawing.Image img = new Bitmap(UploadImage.InputStream); img.Save(path); return View(); }
MemoryStream.GetBuffer() can return extra empty bytes at the end of the byte[], but you can fix that by using MemoryStream.ToArray() instead. However, I found this alternative to work perfectly for all file types: using (var binaryReader = new BinaryReader(file.InputStream)) { byte[] array = binaryReader.ReadBytes(file.ContentLength); } Here's my full code: Document Class: public class Document { public int? DocumentID { get; set; } public string FileName { get; set; } public byte[] Data { get; set; } public string ContentType { get; set; } public int? ContentLength { get; set; } public Document() { DocumentID = 0; FileName = "New File"; Data = new byte[] { }; ContentType = ""; ContentLength = 0; } } File Download: [HttpGet] public ActionResult GetDocument(int? documentID) { // Get document from database var doc = dataLayer.GetDocument(documentID); // Convert to ContentDisposition var cd = new System.Net.Mime.ContentDisposition { FileName = doc.FileName, // Prompt the user for downloading; set to true if you want // the browser to try to show the file 'inline' (display in-browser // without prompting to download file). Set to false if you // want to always prompt them to download the file. Inline = true, }; Response.AppendHeader("Content-Disposition", cd.ToString()); // View document return File(doc.Data, doc.ContentType); } File Upload: [HttpPost] public ActionResult GetDocument(HttpPostedFileBase file) { // Verify that the user selected a file if (file != null && file.ContentLength > 0) { // Get file info var fileName = Path.GetFileName(file.FileName); var contentLength = file.ContentLength; var contentType = file.ContentType; // Get file data byte[] data = new byte[] { }; using (var binaryReader = new BinaryReader(file.InputStream)) { data = binaryReader.ReadBytes(file.ContentLength); } // Save to database Document doc = new Document() { FileName = fileName, Data = data, ContentType = contentType, ContentLength = contentLength, }; dataLayer.SaveDocument(doc); // Show success ... return RedirectToAction("Index"); } else { // Show error ... return View("Foo"); } } View (snippet): @using (Html.BeginForm("GetDocument", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { <input type="file" name="file" /> <input type="submit" value="Upload File" /> }
HTML:
@using (Html.BeginForm("StoreMyCompany", "MyCompany", FormMethod.Post, new { id = "formMyCompany", enctype = "multipart/form-data" })) { <div class="form-group"> @Html.LabelFor(model => model.modelMyCompany.Logo, htmlAttributes: new { @class = "control-label col-md-3" }) <div class="col-md-6"> <input type="file" name="Logo" id="fileUpload" accept=".png,.jpg,.jpeg,.gif,.tif" /> </div> </div> <br /> <div class="form-group"> <div class="col-md-offset-3 col-md-6"> <input type="submit" value="Save" class="btn btn-success" /> </div> </div> }
代码背后:
public ActionResult StoreMyCompany([Bind(Exclude = "Logo")]MyCompanyVM model) { try { byte[] imageData = null; if (Request.Files.Count > 0) { HttpPostedFileBase objFiles = Request.Files["Logo"]; using (var binaryReader = new BinaryReader(objFiles.InputStream)) { imageData = binaryReader.ReadBytes(objFiles.ContentLength); } } if (imageData != null && imageData.Length > 0) { //Your code } dbo.SaveChanges(); return RedirectToAction("MyCompany", "Home"); } catch (Exception ex) { Utility.LogError(ex); } return View(); }
Checkout my solution
public string SaveFile(HttpPostedFileBase uploadfile, string saveInDirectory="/", List<string> acceptedExtention =null) { acceptedExtention = acceptedExtention ?? new List<String>() {".png", ".Jpeg"};//optional arguments var extension = Path.GetExtension(uploadfile.FileName).ToLower(); if (!acceptedExtention.Contains(extension)) { throw new UserFriendlyException("Unsupported File type"); } var tempPath = GenerateDocumentPath(uploadfile.FileName, saveInDirectory); FileHelper.DeleteIfExists(tempPath); uploadfile.SaveAs(tempPath); var fileName = Path.GetFileName(tempPath); return fileName; } private string GenerateDocumentPath(string fileName, string saveInDirectory) { System.IO.Directory.CreateDirectory(Server.MapPath($"~/{saveInDirectory}")); return Path.Combine(Server.MapPath($"~/{saveInDirectory}"), Path.GetFileNameWithoutExtension(fileName) +"_"+ DateTime.Now.Ticks + Path.GetExtension(fileName)); }
add these functions in your base controller
so you can use them in all controllers
checkout how to use it
SaveFile(view.PassportPicture,acceptedExtention:new List<String>() { ".png", ".Jpeg"},saveInDirectory: "content/img/PassportPicture");
and here is a full example
[HttpPost] public async Task<JsonResult> CreateUserThenGenerateToken(CreateUserViewModel view) {// CreateUserViewModel contain two properties of type HttpPostedFileBase string passportPicture = null, profilePicture = null; if (view.PassportPicture != null) { passportPicture = SaveFile(view.PassportPicture,acceptedExtention:new List<String>() { ".png", ".Jpeg"},saveInDirectory: "content/img/PassportPicture"); } if (view.ProfilePicture != null) { profilePicture = SaveFile(yourHttpPostedFileBase, acceptedExtention: new List<String>() { ".png", ".Jpeg" }, saveInDirectory: "content/img/ProfilePicture"); } var input = view.MapTo<CreateUserInput>(); input.PassportPicture = passportPicture; input.ProfilePicture = profilePicture; var getUserOutput = await _userAppService.CreateUserThenGenerateToken(input); return new AbpJsonResult(getUserOutput); //return Json(new AjaxResponse() { Result = getUserOutput, Success = true }); }
Simple way to save multiple files
cshtml
@using (Html.BeginForm("Index","Home",FormMethod.Post,new { enctype = "multipart/form-data" })) { <label for="file">Upload Files:</label> <input type="file" multiple name="files" id="files" /><br><br> <input type="submit" value="Upload Files" /> <br><br> @ViewBag.Message }
调节器
[HttpPost] public ActionResult Index(HttpPostedFileBase[] files) { foreach (HttpPostedFileBase file in files) { if (file != null && file.ContentLength > 0) try { string path = Path.Combine(Server.MapPath("~/Files"), Path.GetFileName(file.FileName)); file.SaveAs(path); ViewBag.Message = "File uploaded successfully"; } catch (Exception ex) { ViewBag.Message = "ERROR:" + ex.Message.ToString(); } else { ViewBag.Message = "You have not specified a file."; } } return View(); }
In Controller
if (MyModal.ImageFile != null) { MyModal.ImageURL = string.Format("{0}.{1}", Guid.NewGuid().ToString(), MyModal.ImageFile.FileName.Split('.').LastOrDefault()); if (MyModal.ImageFile != null) { var path = Path.Combine(Server.MapPath("~/Content/uploads/"), MyModal.ImageURL); MyModal.ImageFile.SaveAs(path); } }
In View
<input type="hidden" value="" name="..."><input id="ImageFile" type="file" name="ImageFile" src="@Model.ImageURL">
In Modal Class
public HttpPostedFileBase ImageFile { get; set; }
Create a folder as uploads in Content folder in project
Since i have found issue uploading file in IE browser i would suggest to handle it like this.
视图
@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { <input type="file" name="file" /> <input type="submit" value="Submit" /> }
调节器
public class HomeController : Controller { public ActionResult UploadFile() { return View(); } [HttpPost] public ActionResult UploadFile(MyModal Modal) { string DocumentName = string.Empty; string Description = string.Empty; if (!String.IsNullOrEmpty(Request.Form["DocumentName"].ToString())) DocumentName = Request.Form["DocumentName"].ToString(); if (!String.IsNullOrEmpty(Request.Form["Description"].ToString())) Description = Request.Form["Description"].ToString(); if (!String.IsNullOrEmpty(Request.Form["FileName"].ToString())) UploadedDocument = Request.Form["FileName"].ToString(); HttpFileCollectionBase files = Request.Files; string filePath = Server.MapPath("~/Root/Documents/"); if (!(Directory.Exists(filePath))) Directory.CreateDirectory(filePath); for (int i = 0; i < files.Count; i++) { HttpPostedFileBase file = files[i]; // Checking for Internet Explorer if (Request.Browser.Browser.ToUpper() == "IE" || Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER") { string[] testfiles = file.FileName.Split(new char[] { '\\' }); fname = testfiles[testfiles.Length - 1]; UploadedDocument = fname; } else { fname = file.FileName; UploadedDocument = file.FileName; } file.SaveAs(fname); return RedirectToAction("List", "Home"); }