写在前面

上篇文章通过iframe实现了文件的无刷新上传。这篇我们将实现文件的下载与删除。

系列文章

[EF]vs15+ef6+mysql code first方式

[实战]MVC5+EF6+MySql企业网盘实战(1)

[实战]MVC5+EF6+MySql企业网盘实战(2)——用户注册

[实战]MVC5+EF6+MySql企业网盘实战(3)——验证码

[实战]MVC5+EF6+MySql企业网盘实战(4)——上传头像

[Bootstrap]modal弹出框

[实战]MVC5+EF6+MySql企业网盘实战(5)——登录界面,头像等比例压缩

[实战]MVC5+EF6+MySql企业网盘实战(5)——页面模板

[实战]MVC5+EF6+MySql企业网盘实战(5)——ajax方式注册

[实战]MVC5+EF6+MySql企业网盘实战(6)——ajax方式登录

[实战]MVC5+EF6+MySql企业网盘实战(7)——文件上传

[实战]MVC5+EF6+MySql企业网盘实战(8)——文件下载、删除

核心代码

上篇实现文件的上传,需要加上一段逻辑,判断上传的文件大小+网盘中所有文件的大小是否已经大于个人网盘的实际容量,如果大于则给予提示,所以,文件上传的代码修改后如下所示:

     [HttpPost]
public void UploadFile(string filePath)
{
UserInfo userInfo = Session["user"] as UserInfo;
if (userInfo == null)
{
RedirectToAction("Login", "UserInfo");
}
var files = Request.Files;
if (files.Count > )
{
var file = files[];
string fileName = file.FileName;
Stream inputStream = file.InputStream;
string fileSaveFolder = Request.MapPath("~/NetDisk/" + userInfo.UserName);
if (!string.IsNullOrEmpty(filePath))
{
fileSaveFolder = Path.Combine(fileSaveFolder, filePath);
} //如果目标不存在,则创建
if (!Directory.Exists(fileSaveFolder))
{
Directory.CreateDirectory(fileSaveFolder); }
byte[] buffer = new byte[inputStream.Length];
//判断是否已经超出个人网盘大小
int myDiskSize = _myFileServiceRepository.FindAll(x => x.User.Id == userInfo.Id).Sum(x => x.FileSize);
//如果已经超出网盘大小,则给出提示
if (myDiskSize + buffer.Length > userInfo.NetDiskSize)
{
AlertMsg("对不起,您的网盘空间不足,请清理后再次上传,或联系管理员进行扩容。", "");
return;
}
inputStream.Read(buffer, , buffer.Length);
string strFileMd5 = MD5Helper.GetMD5FromFile(buffer);
string fileSavePath = Path.Combine(fileSaveFolder, filePath);
fileSavePath = Path.Combine(fileSaveFolder, fileName);
//如果文件已经存在
if (System.IO.File.Exists(fileSavePath))
{
//对文件进行重命名
fileName = ReNameHelper.FileReName(fileSavePath);
fileSavePath = Path.Combine(fileSaveFolder, fileName);
}
file.SaveAs(fileSavePath);
var currentUser = _userInfoServiceRepository.Find(x => x.Id == userInfo.Id);
MyFile myFile = new MyFile()
{
FileMd5 = strFileMd5,
ModifyDt = DateTime.Now,
IsDelete = false,
FileSize = buffer.Length,
FilePath = "/NetDisk/" + userInfo.UserName + "/" + fileName,
FileExt = Path.GetExtension(fileSavePath),
CreateDt = DateTime.Now,
FileName = fileName,
FileIcon = GetFileIcon(Path.GetExtension(fileSavePath)),
User = currentUser
};
//保存数据库
_myFileServiceRepository.Add(myFile);
_myFileServiceRepository.SaveChanges();
string json = new JavaScriptSerializer().Serialize(myFile);
AlertMsg("上传成功", json);
}
}

UploadFile

今天发现一个bug,发现在路径存储的时候,如果文件名中有中文名称,则会出现乱码的问题,这里只能手动进行数据库字段的编码修改了。

下载的代码:

    public void DownLoadFile(string fileId)
{
UserInfo userInfo = Session["user"] as UserInfo;
if (userInfo == null)
{
RedirectToAction("Login", "UserInfo");
return;
}
if (string.IsNullOrEmpty(fileId))
{
throw new ArgumentNullException("fileId is errror");
}
int id = Convert.ToInt32(fileId);
var findFile = _myFileServiceRepository.Find(x => x.Id == id);
if (findFile == null)
{
AlertMsg("文件不存在", "");
return;
}
string filePath = Request.MapPath(findFile.FilePath);
//以字符流的形式下载文件
FileStream fs = new FileStream(filePath, FileMode.Open);
byte[] bytes = new byte[(int)fs.Length];
fs.Read(bytes, , bytes.Length);
fs.Close();
Response.ContentType = "application/octet-stream";
//通知浏览器下载文件而不是打开
Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(findFile.FileName, System.Text.Encoding.UTF8));
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
}
            <tbody role="alert" aria-live="polite" aria-relevant="all">
@{int i = 0;}
@foreach (var item in Model)
{
i++;
<tr class="i%2==0?'even':'odd'">
<td class=" even sorting_1"><img src="@item.FileIcon" alt="" />@item.FileName</td>
<td class="center ">@item.FileSize 字节</td>
<td class="center ">@item.ModifyDt</td> <td class="center ">
<a class="btn btn-success" href="/Home/DownLoadFile?fileId=@item.Id">
<i class="glyphicon glyphicon-zoom-in icon-white"></i>
下载
</a>
<a class="btn btn-info" href="#">
<i class="glyphicon glyphicon-edit icon-white"></i>
编辑
</a>
<a class="btn btn-danger" href="#">
<i class="glyphicon glyphicon-trash icon-white"></i>
删除
</a>
</td>
</tr> }
</tbody>

测试

完善动态创建的上传文件信息

    //上传成功后,单击确定,更新刚刚拼接文件信息
function showMsg(msg, callbackInfo) {
if (msg) {
$(".modal-body").html(msg);
//回调信息
$("#hdcallbackInfo").val(callbackInfo);
console.log(callbackInfo);
//为确定按钮注册单击事件,确定后更新拼接在列表上的文件信息
$('#fileListSure').click(function () {
var fileInfo = $("#hdcallbackInfo").val();
console.log(fileInfo);
fileInfo = JSON.parse(fileInfo);
$("#fileDownLoad").attr("href", "/Home/DownLoadFile?fileId=" + fileInfo.Id);
$("#fileName").html('<img src="' + fileInfo.FileIcon + '" id="fileicon" alt="" />' + fileInfo.FileName + '');
});
$("#myModal").modal("show");
};
};
 $("#btnFile").change(function () {
var files = this.files;
for (var i = 0; i < files.length; i++) {
var file = files[i];
console.log(file);
$(' <tr class="odd"> <td class=" even sorting_1" id="fileName"><img src="/Content/Images/othertype.png" id="fileicon" alt="" />' + file.name + '</td><td class="center">' + file.size + ' 字节</td><td class="center ">' + CurentTime() + '</td><td class="center "> <a class="btn btn-success" href="#" id="fileDownLoad"><i class="glyphicon glyphicon-zoom-in icon-white"></i> 下载 </a><a class="btn btn-info" href="#" id="fileEdit"> <i class="glyphicon glyphicon-edit icon-white"></i> 编辑 </a><a class="btn btn-danger" href="#"><i class="glyphicon glyphicon-trash icon-white" id="fileDelete"></i> 删除 </a> </td></tr>').appendTo($('#fileList tbody'));
};
$('#fileForm').submit();
});

删除,这里进行逻辑删除,为以后客户端的开发考虑,如果是客户端进行上传,可以采用md5的比对,如果文件已经存在,则复制一条信息即可,可实现文件的秒传。

        public void DeleteFile(string fileId)
{
UserInfo userInfo = Session["user"] as UserInfo;
if (userInfo == null)
{
RedirectToAction("Login", "UserInfo");
return;
}
if (string.IsNullOrEmpty(fileId))
{
throw new ArgumentNullException("fileId is errror");
}
int id = Convert.ToInt32(fileId);
var findFile = _myFileServiceRepository.Find(x => x.Id == id);
if (findFile == null)
{
AlertMsg("文件不存在", "");
return;
}
findFile.IsDelete = true;
_myFileServiceRepository.Update(findFile);
int count = _myFileServiceRepository.SaveChanges();
if (count > )
{
var response = new { code = , fileId = findFile.Id };
Response.Write(new JavaScriptSerializer().Serialize(response));
}
}

前端代码

@model IEnumerable<Wolfy.NetDisk.Model.MyFile>

@{
ViewBag.Title = "FileList";
Layout = "~/Views/Shared/_Layout.cshtml"; }
<button id="btnUpload" class="btn-primary">上传文件</button>
<button class="btn-primary">新建文件夹</button> <div class="box-content" id="fileList">
<div class="dataTables_wrapper" role="grid">
<table id="fileList" class="table table-striped table-bordered responsive" id="DataTables_Table_0" aria-describedby="DataTables_Table_0_info">
<thead>
<tr role="row">
<th class="sorting_asc" role="columnheader" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-sort="ascending" aria-label="Username: activate to sort column descending" style="width: 312px;">文件名</th> <th class="sorting" role="columnheader" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Role: activate to sort column ascending" style="width: 144px;">大小</th>
<th class="sorting" role="columnheader" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Date registered: activate to sort column ascending" style="width: 263px;">修改日期</th> <th class="sorting" role="columnheader" tabindex="0" aria-controls="DataTables_Table_0" rowspan="1" colspan="1" aria-label="Actions: activate to sort column ascending" style="width: 549px;">操作</th>
</tr>
</thead> <tbody role="alert" aria-live="polite" aria-relevant="all">
@{int i = 0;}
@foreach (var item in Model)
{
i++;
<tr class="i%2==0?'even':'odd'" id="tr-@item.Id">
<td class=" even sorting_1"><img src="@item.FileIcon" alt="" />@item.FileName</td>
<td class="center ">@item.FileSize 字节</td>
<td class="center ">@item.ModifyDt</td> <td class="center ">
<a class="btn btn-success" href="/Home/DownLoadFile?fileId=@item.Id">
<i class="glyphicon glyphicon-zoom-in icon-white"></i>
下载
</a>
<a class="btn btn-info" href="#">
<i class="glyphicon glyphicon-edit icon-white"></i>
编辑
</a>
<a class="btn btn-danger" href="javascript:void(0)" onclick="deleteFile(@item.Id)">
<i class="glyphicon glyphicon-trash icon-white"></i>
删除
</a>
</td>
</tr> }
</tbody>
</table>
</div>
</div> <form action="UploadFile" id="fileForm" method="post" enctype="multipart/form-data" target="fileFrame">
<input type="file" accept="*/*" style="display:none" id="btnFile" name="fileData" />
<input type="hidden" id="hdFilePath" name="filePath" value="" />
<input type="hidden" id="hdcallbackInfo" name="name" value="" />
</form> <iframe style="display:none" name="fileFrame" id="fileFrame"></iframe>
<script>
//上传成功后,单击确定,更新刚刚拼接文件信息
function showMsg(msg, callbackInfo) {
if (msg) {
$(".modal-body").html(msg);
//回调信息
$("#hdcallbackInfo").val(callbackInfo);
console.log(callbackInfo);
//为确定按钮注册单击事件,确定后更新拼接在列表上的文件信息
$('#fileListSure').click(function () {
var fileInfo = $("#hdcallbackInfo").val();
console.log(fileInfo);
fileInfo = JSON.parse(fileInfo);
$("#fileDownLoad").attr("href", "/Home/DownLoadFile?fileId=" + fileInfo.Id);
$("#fileName").html('<img src="' + fileInfo.FileIcon + '" id="fileicon" alt="" />' + fileInfo.FileName + ''); });
$("#myModal").modal("show");
};
}; function deleteFile(fileId) {
console.log(fileId);
$.getJSON("/Home/DeleteFile?fileId="+fileId,function(data){
console.log(data.code);
if (data.code==4) { $("#tr-"+fileId).remove();
}; });
};
function CurentTime() {
var now = new Date();
var year = now.getFullYear(); //年
var month = now.getMonth() + 1; //月
var day = now.getDate(); //日
var hh = now.getHours(); //时
var mm = now.getMinutes(); //分
var clock = year + "-";
if (month < 10)
clock += "0";
clock += month + "-";
if (day < 10)
clock += "0";
clock += day + " ";
if (hh < 10)
clock += "0";
clock += hh + ":";
if (mm < 10) clock += '0';
clock += mm;
return (clock);
};
$('#btnUpload').click(function () {
$("#btnFile").click();
});
$("#btnFile").change(function () {
var files = this.files;
for (var i = 0; i < files.length; i++) {
var file = files[i];
console.log(file);
$(' <tr class="odd"> <td class=" even sorting_1" id="fileName"><img src="/Content/Images/othertype.png" id="fileicon" alt="" />' + file.name + '</td><td class="center">' + file.size + ' 字节</td><td class="center ">' + CurentTime() + '</td><td class="center "> <a class="btn btn-success" href="#" id="fileDownLoad"><i class="glyphicon glyphicon-zoom-in icon-white"></i> 下载 </a><a class="btn btn-info" href="#" id="fileEdit"> <i class="glyphicon glyphicon-edit icon-white"></i> 编辑 </a><a class="btn btn-danger" href="#"><i class="glyphicon glyphicon-trash icon-white" id="fileDelete"></i> 删除 </a> </td></tr>').appendTo($('#fileList tbody'));
};
$('#fileForm').submit();
}); </script>

FileList.cshtml

总结

完善上传逻辑,并实现文件的下载与逻辑删除,下一步将实现新建文件夹,并合并新建文件夹与上传文件的逻辑。

[实战]MVC5+EF6+MySql企业网盘实战(8)——文件下载、删除的更多相关文章

  1. [实战]MVC5+EF6+MySql企业网盘实战(28)——其他列表

    写在前面 本篇文章将实现,其他文件类型的列表. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网盘实战(1) [实战]MVC5+EF ...

  2. [实战]MVC5+EF6+MySql企业网盘实战(27)——应用列表

    写在前面 本篇文章将实现应用列表,同样和其他列表的不同之处,在于查询条件的不同. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网盘 ...

  3. [实战]MVC5+EF6+MySql企业网盘实战(4)——上传头像

    写在前面 最近又开始忙了,工期紧比较赶,另外明天又要去驾校,只能一个功能一个功能的添加了,也许每次完成的功能确实不算什么,等将功能都实现了,然后在找一个好点的ui对前端重构一下. 系列文章 [EF]v ...

  4. [实战]MVC5+EF6+MySql企业网盘实战(2)——验证码

    写在前面 断断续续,今天算是把验证码的东东弄出来了. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网盘实战(1) [实战]MVC5 ...

  5. [实战]MVC5+EF6+MySql企业网盘实战(2)——用户注册

    写在前面 上篇文章简单介绍了项目的结构,这篇文章将实现用户的注册.当然关于漂亮的ui,这在追后再去添加了,先将功能实现.也许代码中有不合适的地方,也只有在之后慢慢去优化了. 系列文章 [EF]vs15 ...

  6. [实战]MVC5+EF6+MySql企业网盘实战(1)

    写在前面 不久前,一个朋友让帮他弄一个单位的企业网盘的管理站点,一直忙,最近抽出了点时间,也想琢磨琢磨mvc,ef,mysql,这算是边琢磨,边实践吧. 系列文章 [实战]MVC5+EF6+MySql ...

  7. [实战]MVC5+EF6+MySql企业网盘实战(26)——音乐列表

    写在前面 本篇文章将实现,音乐列表,同样和其他列表的不同之处,在于查询条件的不同. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网 ...

  8. [实战]MVC5+EF6+MySql企业网盘实战(25)——种子列表

    写在前面 上篇文章实现了视频列表,本篇文章继续实现其他的文件列表.功能相似.这里就不再赘述. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MyS ...

  9. [实战]MVC5+EF6+MySql企业网盘实战(24)——视频列表

    写在前面 上篇文章实现了文档列表,所以实现视频列表就依葫芦画瓢就行了. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网盘实战(1) ...

  10. [实战]MVC5+EF6+MySql企业网盘实战(23)——文档列表

    写在前面 上篇文章实现了图片列表,这篇文章实现文档列表将轻车熟路,因为逻辑基本相似,只是查询条件的不同.这里将txt,doc,docx,ppt,pptx,xls,xlsx的文件都归为文档列表中. 系列 ...

随机推荐

  1. php开启压缩gzip

    php服务的开启压缩,节省带宽 看是否开启压缩的网站 http://www.cnblogs.com/GaZeon/p/5421906.html 找到php.ini,修改下面的 ,重启php-fpm z ...

  2. git 撤销上一次 commit

    1.本地 commit,没有推到远程仓库 可以 git reset --soft <commit_id>,commit_id 是要回退到的某一版本 然后再进行修改,再commit, 如果需 ...

  3. 线程同步API及它们的属性

    头文件:<pthread.h> 编译记得加 -lpthread库 1:互斥锁(mutex) 1.1:互斥锁API 数据类型:pthread_mutex_t // 初始化一个互斥锁 int ...

  4. std::sort运行出core(segment fault)

    http://note.youdao.com/noteshare?id=6aae09345e85ab55fe24ac959118a747

  5. 新生代Eden与两个Survivor区的解释

    文章出处:http://ifeve.com/jvm-yong-generation/ 聊聊JVM的年轻代 1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分 ...

  6. 前端PHP入门-032-异常处理-应用级别

    禁止显示错误 在php.ini配置文件中.我们可以控制php的错误显示状态. php.ini中有一个专门的配置项: display_errors 这个选项设置是否将错误信息输出到网页,或者对用户隐藏而 ...

  7. 前端PHP入门-027-数组常用函数-掌握级别

    下面的函数一定要到熟悉甚至到掌握级别. 这些函数,也是面试中基础面试中最爱问到的问题. 函数名 功能 array_combine() 生成一个数组,用一个数组的值作为键名,另一个数组值作为值 rang ...

  8. 1.redis设计与实现--简单动态字符串

    1.redis没有使用c语言的字符串表示,而是使用更加适合自己的SDS(simple dynamic string),简单动态字符串,结构如下: 2.sys与c字符串的对比: 3.总结: redis采 ...

  9. Parencodings(模拟)

    ZOJ Problem Set - 1016 Parencodings Time Limit: 2 Seconds      Memory Limit: 65536 KB Let S = s1 s2 ...

  10. 桥接模式_NAT模式_仅主机模式_模型图.ziw

      2017年1月12日, 星期四 桥接模式_NAT模式_仅主机模式_模型图   null