File Upload ASP.NET MVC 3.0
我要在ASP.NET-MVC中上载文件。如何使用html
您不使用文件输入控件。ASP.NET MVC中未使用服务器端控件。查看下面的博客文章,其中演示了如何在ASP.NET MVC中实现这一点。
因此,首先创建一个包含文件输入的HTML表单:
1 2 3 4 5 | @using (Html.BeginForm("Index","Home", FormMethod.Post, new { enctype ="multipart/form-data" })) { <input type="file" name="file" /> <input type="submit" value="OK" /> } |
然后你会有一个控制器来处理上传:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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"); } } |
传输到
1 2 3 4 | using (MemoryStream ms = new MemoryStream()) { file.InputStream.CopyTo(ms); byte[] array = ms.GetBuffer(); } |
要将输入流直接传输到数据库中,而不将其存储在内存中,您可以使用从这里获取的类,并进行一些更改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | 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 } |
用法:
1 2 3 4 5 6 7 8 9 10 | 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()可以在字节[]的末尾返回额外的空字节,但可以使用memoryStream.toArray()来修复此问题。但是,我发现这个替代方法对于所有文件类型都非常有效:
1 2 3 4 | using (var binaryReader = new BinaryReader(file.InputStream)) { byte[] array = binaryReader.ReadBytes(file.ContentLength); } |
这是我的完整代码:
文档类别:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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; } } |
文件下载:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | [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); } |
文件上传:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | [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"); } } |
视图(摘录):
1 2 3 4 5 | @using (Html.BeginForm("GetDocument","Home", FormMethod.Post, new { enctype ="multipart/form-data" })) { <input type="file" name="file" /> <input type="submit" value="Upload File" /> } |
通常,您还希望传递一个视图模型,而不是唯一的一个文件。在下面的代码中,您将发现一些其他有用的功能:
- 检查文件是否已附加
- 正在检查文件大小是否为0
- 检查文件大小是否大于4 MB
- 检查文件大小是否小于100字节
- 正在检查文件扩展名
可以通过以下代码完成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | [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); } |
确保你有
1 | @Html.ValidationMessage("uploadError") |
在您的视图中查看验证错误。
还要记住,默认的最大请求长度是4MB(maxrequestlength=4096),要上载更大的文件,必须在web.config中更改此参数:
1 2 | <system.web> <httpRuntime maxRequestLength="40960" executionTimeout="1100" /> |
(这里40960=40 MB)。
执行超时是秒的整数。您可能需要将其更改为允许上载大量文件。
观点:
1 2 3 4 | <form action="Categories/Upload" enctype="multipart/form-data" method="post"> <input type="file" name="Image"> <input type="submit" value="Save"> </form> |
控制器中的以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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); } ... } |
我必须使用命令以100kb的文件块和数据库中最后一个上载文件存储区的形式上载文件。希望对你有帮助。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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(淘汰JS)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | 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代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | Attachments@Html.AttachmentPicker("AC") <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"></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"></td> <td style="text-align: center" class="col-xs-4"></td> <td style="text-align: center" class="col-xs-1"><button class="btn btn-primary" data-bind="click:$root.deleteAttachmentRecord"><i class="icon-trash"></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"> </td> <td style="text-align: center"><button class="btn btn-primary" data-bind="click:cancel"><i class="icon-trash"></button></td> </tr> <!-- /ko --> </tfoot> </table> <span>No Records found.</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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(); } |
我的操作方法和上面差不多,我将向您展示我的代码,以及如何将它与mysql数据库一起使用…
数据库中的文档表-
int id(pk),字符串URL,字符串说明,CreatedBy永生化数据复制的
上面的代码id是主键,url是文件名(文件类型在末尾),文件描述是在文档视图中输出的,由上载文件的人创建,tenancyid,dateuploaded
在视图中,必须定义enctype,否则它将无法正常工作。
1 2 3 4 5 6 7 | @using (Html.BeginForm("Upload","Document", FormMethod.Post, new { enctype ="multipart/form-data" })) { <label for="file">Upload a document:</label> <input type="file" name="file" id="file" /> } |
上面的代码将提供浏览按钮,然后在我的项目中,我有一个基本上称为isvalidimage的类,它只检查文件大小是否在指定的最大大小之下,检查它是否是img文件,这都在一个类bool函数中。所以如果真的返回真的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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; } |
所以在控制器中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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; |
给出完整的解决方案
在MVC视图中首先使用.cshtml中的输入
1 2 | <input type="file" id="UploadImg" /></br> <img id="imgPreview" height="200" width="200" /> |
现在调用Ajax调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | $("#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调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | [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文件中编写以下代码。
1 | <input name="Image" type="file" class="form-control" id="resume" /> |
然后在控制器中输入以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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("~") +"\ esume\")) { System.IO.Directory.CreateDirectory(Server.MapPath("~") +"\ esume\"); } string documentpath = Server.MapPath("~") +"\ esume\" + 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层。
以下是我的工作示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | [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文件中放入此代码
1 2 3 4 5 6 7 | @using (Html.BeginForm("UploadImageAction","Admin", FormMethod.Post, new { enctype ="multipart/form-data", id ="myUploadForm" })) { @Html.UploadFile("UploadImage") <button class="button">Upload Image</button> } |
然后为upload标记创建一个htmlhelper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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()); } } |
最后上传你的文件
1 2 3 4 5 6 7 8 9 10 | [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(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 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" /> } |
使用FormData上载文件
CSHML文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var files = $("#file").get(0).files; if (files.length > 0) { data.append("filekey", files[0]);} $.ajax({ url: '@Url.Action("ActionName","ControllerName")', type:"POST", processData: false, data: data, dataType: 'json', contentType: false, success: function (data) { var response=data.JsonData; }, error: function (er) { } }); |
服务器端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | if (System.Web.HttpContext.Current.Request.Files.AllKeys.Any()) { var pic = System.Web.HttpContext.Current.Request.Files["filekey"]; HttpPostedFileBase filebase = new HttpPostedFileWrapper(pic); var fileName = Path.GetFileName(filebase.FileName); string fileExtension = System.IO.Path.GetExtension(fileName); if (fileExtension ==".xls" || fileExtension ==".xlsx") { string FileName = Guid.NewGuid().GetHashCode().ToString("x"); string dirLocation = Server.MapPath("~/Content/PacketExcel/"); if (!Directory.Exists(dirLocation)) { Directory.CreateDirectory(dirLocation); } string fileLocation = Server.MapPath("~/Content/PacketExcel/") + FileName + fileExtension; filebase.SaveAs(fileLocation); } } |
Simple way to save multiple files
cshtml
1 2 3 4 5 6 7 8 | @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" /> <input type="submit" value="Upload Files" /> @ViewBag.Message } |
控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | [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(); } |
由于我在IE浏览器中发现上传文件的问题,我建议这样处理。
视图
1 2 3 4 5 | @using (Html.BeginForm("UploadFile","Home", FormMethod.Post, new { enctype ="multipart/form-data" })) { <input type="file" name="file" /> <input type="submit" value="Submit" /> } |
控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 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"); } |
签出我的解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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)); } |
在您的
检查如何使用它
1 2 3 4 5 6 7 8 9 10 | SaveFile(view.PassportPicture,acceptedExtention:new List<String>() {".png",".Jpeg <div class="suo-content">[collapse title=""]<ul><li>如果你必须发送日期,表格和上传文件的文本怎么办?</li></ul>[/collapse]</div><hr><P>在控制器中</P>[cc lang="csharp"] 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); } } |
在视野中
1 | <input type="hidden" value="" name="..."><input id="ImageFile" type="file" name="ImageFile" src="@Model.ImageURL"> |
情态课堂
1 | public HttpPostedFileBase ImageFile { get; set; } |
在Project的内容文件夹中创建上载文件夹
虽然我在Donnetfiddle上为你做了一个样本项目,但大多数答案似乎都是合法的。
我正在为csv工作使用lumenworks.framework,但它不是必须的。
演示
视图
1 2 3 4 5 6 7 8 | @using (Html.BeginForm("Index","Home","POST")) { <label for="file">Upload Files:</label> <input type="file" multiple name="files" id="files" class="form-control"/> <input type="submit" value="Upload Files" class="form-control"/> |
控制器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | [HttpPost] public ActionResult Index(HttpPostedFileBase upload) { if (ModelState.IsValid) { if (upload != null && upload.ContentLength > 0) { // Validation content length if (upload.FileName.EndsWith(".csv") || upload.FileName.EndsWith(".CSV")) { //extention validation ViewBag.Result ="Correct File Uploaded"; } } } return View(); } |
Html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @using (Html.BeginForm("StoreMyCompany","MyCompany", FormMethod.Post, new { id ="formMyCompany", enctype ="multipart/form-data" })) { @Html.LabelFor(model => model.modelMyCompany.Logo, htmlAttributes: new { @class ="control-label col-md-3" }) <input type="file" name="Logo" id="fileUpload" accept=".png,.jpg,.jpeg,.gif,.tif" /> <br /> <input type="submit" value="Save" class="btn btn-success" /> } |
代码落后:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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(); } |
在执行文件上传概念时,我也遇到了同样的错误。我知道开发人员为这个问题提供了很多答案。
尽管我回答这个问题的原因是,由于下面提到的疏忽错误而产生了这个错误。
1 | <input type="file" name="uploadedFile" /> |
在给出name属性的同时,确保您的控制器参数也具有相同的name值"uploadedfile"。这样地:
1 2 3 4 5 | [HttpPost] public ActionResult FileUpload(HttpPostedFileBase uploadedFile) { } |
否则它就不会被映射。