(前言:这个问题是关于2011年发布的ASP.NET MVC 3.0,而不是关于2019年发布的ASP.NETCore 3.0)
我想用asp.net mvc上传文件。如何使用html输入文件控件上载文件?
(前言:这个问题是关于2011年发布的ASP.NET MVC 3.0,而不是关于2019年发布的ASP.NETCore 3.0)
我想用asp.net mvc上传文件。如何使用html输入文件控件上载文件?
当前回答
我在做文件上传概念时也遇到过同样的错误。我知道开发人员为这个问题提供了很多答案。
尽管我回答这个问题的原因是,由于下面提到的疏忽错误,我犯了这个错误。
<input type="file" name="uploadedFile" />
在指定name属性时,请确保控制器参数也具有相同的名称值“uploadedFile”。这样地:
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase uploadedFile)
{
}
否则它不会被映射。
其他回答
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" />
}
保存多个文件的简单方法
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();
}
由于我在IE浏览器中发现了上传文件的问题,我建议这样处理。
View
@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");
}
我的方法和上面差不多,我将向您展示我的代码以及如何使用MYSSQL数据库。。。
数据库中的文档表-
int Id(PK),字符串Url,字符串描述,创建者,租户ID上传日期
上面的代码ID是主键,URL是文件的名称(末尾有文件类型),要在文档视图中输出的文件描述,CreatedBy是上载文件的人,tenncyId,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>
}
上面的代码将给你一个浏览按钮,然后在我的项目中,我有一个基本上名为IsValidImage的类,它只是检查文件大小是否在指定的最大大小之下,检查它是否是IMG文件,这都在类bool函数中。所以,如果true返回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;
另一种传输到字节[]的方法(用于保存到DB)。
@Arthur的方法工作得很好,但不能完美复制,因此MS Office文档在从数据库检索后可能无法打开。MemoryStream.GetBuffer()可以在字节[]的末尾返回额外的空字节,但可以使用MemoryStream.ToArray()来解决这个问题。然而,我发现这个替代方案可以完美地适用于所有文件类型:
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");
}
}
视图(代码段):
@using (Html.BeginForm("GetDocument", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="Upload File" />
}