(前言:这个问题是关于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输入文件控件上载文件?
当前回答
另一种传输到字节[]的方法(用于保存到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" />
}
其他回答
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" />
}
我在做文件上传概念时也遇到过同样的错误。我知道开发人员为这个问题提供了很多答案。
尽管我回答这个问题的原因是,由于下面提到的疏忽错误,我犯了这个错误。
<input type="file" name="uploadedFile" />
在指定name属性时,请确保控制器参数也具有相同的名称值“uploadedFile”。这样地:
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase uploadedFile)
{
}
否则它不会被映射。
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();
}
在控制器中
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);
}
}
在视图中
<input type="hidden" value="" name="..."><input id="ImageFile" type="file" name="ImageFile" src="@Model.ImageURL">
在模态类中
public HttpPostedFileBase ImageFile { get; set; }
在项目的Content文件夹中创建上载文件夹
如果你碰巧像我一样在这里跌跌撞撞,想知道尽管代码正确,为什么你的代码仍然不工作。然后,请在输入控件中查找name属性,您可能会意外错过或从未将其放在首位。
<input class="custom-file-input" name="UploadFile" id="UploadFile" type="file" onchange="ValidateFile(this);" accept=".xls, .xlsx">