(前言:这个问题是关于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输入文件控件上载文件?
当前回答
使用formdata上载文件
.cshtml文件
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) { }
});
服务器端代码
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);
}
}
其他回答
由于我在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");
}
您不使用文件输入控件。ASP.NET MVC中未使用服务器端控件。查看下面的博客文章,其中说明了如何在ASP.NET MVC中实现这一点。
因此,您将首先创建一个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");
}
}
如果你碰巧像我一样在这里跌跌撞撞,想知道尽管代码正确,为什么你的代码仍然不工作。然后,请在输入控件中查找name属性,您可能会意外错过或从未将其放在首位。
<input class="custom-file-input" name="UploadFile" id="UploadFile" type="file" onchange="ValidateFile(this);" accept=".xls, .xlsx">
另一种传输到字节[]的方法(用于保存到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" />
}
我的方法和上面差不多,我将向您展示我的代码以及如何使用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;