说明:
前后端代码中均只用到 ASP.NET MVC原生的技术,不需要用到ajax,WebAPI等。
下篇文章【 jQuery + Ajax + WebAPI 上传文件】会介绍使用Ajax POST来上传文件以及使用WebAPI做后台处理的方法。
1. 上传文件
ASP.NET MVC最简单的方式是使用表单来POST文件。
前端代码如下:
<form action="/BulkUpload/UploadFiles" method="post" enctype="multipart/form-data">
<input type="file" />
<input type="submit" value="upload" />
</form>
说明:
action
是表单提交后后台要调用的处理方法。
enctype="multipart/form-data"
这句一定要加上,表明传递的是文件,不是普通数据。
后台代码:
[HttpPost]
public bool UploadFiles()
{
// 文件数为0证明上传不成功
if (Request.Files.Count == 0)
{
throw new Exception("请选择上传文件!");
}
string uploadPath = Server.MapPath("../UploadFiles/");
// 如果UploadFiles文件夹不存在则先创建
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
// 保存文件到UploadFiles文件夹
for (int i = 0; i < Request.Files.Count; ++i)
{
HttpPostedFileBase file = Request.Files[i];
// 文件名为空证明没有选择上传文件
if (file.FileName == "")
{
return false;
}
string filePath = uploadPath + Path.GetFileName(file.FileName);
string fileName = file.FileName;
// 检查上传文件的类型是否合法
string fileExtension = Path.GetExtension(filePath).ToLower();
string fileFilter = ConfigurationManager.AppSettings["FileFilter"];
if (fileFilter.IndexOf(fileExtension) <= -1)
{
Response.Write("对不起!请上传图片!!");
return false;
}
// 如果服务器上已经存在该文件则要修改文件名与其储存路径
while (System.IO.File.Exists(filePath))
{
Random rand = new Random();
fileName = rand.Next().ToString() + "-" + file.FileName;
filePath = uploadPath + Path.GetFileName(fileName);
}
// 把文件的存储路径保存起来
SaveUploadFileInfo(fileName, filePath); // todo:SaveUploadFileInfo方法请自己实现
// 保存文件到服务器
file.SaveAs(filePath);
}
return true;
}
上面用到了配置文件,也列出来一下
<appSettings>
...
<add key="FileFilter" value=".gif|.jpg|.jpeg|.png|" />
...
</appSettings>
2. 下载文件
前端代码:
<input type="submit" value="下载" onclick="downloadFile()"/>
<script type="text/javascript">
function downloadFile() {
window.location.href = "/BulkUpload/DownloadFile";
}
</script>
后台代码:
[HttpGet]
public FileStreamResult DownloadFile()
{
string result = GetUploadFileInfo(); // todo:GetUploadFileInfo方法请自己实现
string[] str = result.Split(',');
string fileName = str[0];
string filePath = str[1];
return File(new FileStream(filePath, FileMode.Open), "application/octet-stream", Server.UrlEncode(fileName));
}
2018/03/21
【Update】
原来的代码里面没有放 SaveUploadFileInfo
和 GetUploadFileInfo
两个方法,那是想着这不是本文的重点。保存到信息到数据库用ADO.NET也好ORM也好,随便搜一下也很多栗子。
我这里只是个demo,不是正式项目,没有保存到数据库,只是保存到了一个文本,而且代码逻辑也没考虑多次上传的问题,而且这也不是文章要讨论的重点。所以没贴出来。
然而有人评论说我的代码是不知道从哪里复制的,我只能说伸手党真是什么样的人都有(那条评论被我冲动删了)。真是无语了,那我就贴完整代码吧。
事先声明!!!下面的代码逻辑不完整,请不要直接使用!!!
// 把上传文件的文件名与存储路径保存到record.txt文件
private void SaveUploadFileInfo(string fileName, string filePath)
{
FileStream fs = new FileStream(@"D:\...\record.txt", FileMode.Create); // 测试的我就把路径写死了
string saveStr = fileName + "," + filePath;
byte[] data = System.Text.Encoding.Default.GetBytes(saveStr);
fs.Write(data, 0, data.Length);
fs.Flush();
fs.Close();
}
// 从record.txt文件获取上传文件的存储路径
private string GetUploadFileInfo()
{
StreamReader sr = new StreamReader(@"D:\...\record.txt", System.Text.Encoding.Default);
string filePath = sr.ReadLine();
sr.Close();
return filePath;
}