(前言:这个问题是关于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输入文件控件上载文件?
当前回答
尽管我在donnetfiddle上为你做了一个示例项目,但大多数答案似乎都足够合理
我正在使用LumenWorks.Framework进行CSV工作,但这不是必须的。
Demo
View
@using (Html.BeginForm("Index", "Home", "POST"))
{
<div class="form-group">
<label for="file">Upload Files:</label>
<input type="file" multiple name="files" id="files" class="form-control"/><br><br>
<input type="submit" value="Upload Files" class="form-control"/>
</div>
控制器:
[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();
}
其他回答
如果你碰巧像我一样在这里跌跌撞撞,想知道尽管代码正确,为什么你的代码仍然不工作。然后,请在输入控件中查找name属性,您可能会意外错过或从未将其放在首位。
<input class="custom-file-input" name="UploadFile" id="UploadFile" type="file" onchange="ValidateFile(this);" accept=".xls, .xlsx">
我的方法和上面差不多,我将向您展示我的代码以及如何使用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;
您不使用文件输入控件。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");
}
}
如果有人想用Ajax上传多个文件,下面是我的文章在Asp.NetMVC中使用Ajax进行多文件上传
要传输到字节[](例如,用于保存到DB):
using (MemoryStream ms = new MemoryStream()) {
file.InputStream.CopyTo(ms);
byte[] array = ms.GetBuffer();
}
若要将输入流直接传输到数据库中,而不将其存储在内存中,您可以使用从此处获取的此类,并稍作更改:
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);
}