文件上传功能学习
- 为什么要记录
为了在以后需要用到这个功能的时候不用像今天一般花那么长时间去百度,做过一遍的功能,却不能够重新还原,我尝试过做word笔记,但换了电脑或者是清理文件夹之后就很难找到当初的文档了,所以还是线上的比较好,只要登录就可以啦~本人还是菜鸟一枚,往各位大神多多指教噢~~ - 上传的核心点
其实上传文件这个功能是一个可以说在很多地方都通用的,我的最难懂点就是在C# 控制器中怎么获取到这个文件,并将他存到服务器上去,因为一个文件里面肯定有这个文件所包括的内容,所以我们需要将整个文件获取,然后再自定义文件存储的路径,最后使用C#特有的获取的文件.SaveAs("文件路径")
函数将其上传至指定的文件路径中去。
我曾经百度尝试过的获取页面传过来的文件的方法有一下几种:
- 1>Request.Files[0].FileName
- 2>HttpContext cxt//HttpContext是封装有关个别 HTTP 请求的所有 HTTP 特定的信息 的一个类
- //然后通过这个类的一个属性即可获得文件
- cxt.Request.Files[0];
-
事实上前台的获取文件方式都一样:
<input type="file" name="uploadify" id="uploadify" />
<div id="AttachGrid"></div>
不同的只是我们传送到后台的方式,我理解为以下几种:
- 直接使用form表单传送,在表单中获取文件类型的(即type=”file”的值),然后通过Submit提交到某个后台控制器。
使用按钮点击式的,当点击某个button时才会触发文件的上传事件,这种方法依赖
$.ajax({
url:"",
data:{},
dataType:"",
success:funcion(){},
error:function(){},
complete:function(){}
})
将文件的名称,路径等信息通过这种方式传至后台控制器通过一个插件:
$.ajaxFileUpload()
$.ajaxFileUpload({
url: '../Tools/UpLoadFiles.ashx',
secureuri: false,
fileElementId: 'uploadify',
//dataType: 'json',
success: function (data, status) {
console.log(data)
var test = $(data).find("pre").html();
console.log(test);
var json = $.parseJSON(test);
console.log(json);
debugger;
var record = {
FID: '',
ATTACH_FILE: json.originalName,
ATTACH_PATH: json.url
}
project.AddRowAttach(record);
}
});
这里是直接调用应用程序处理文件进行上传的,我遇见一个一直没有解决的错误,就是如果我将dataType:”json”的注释去掉,就会报Uncaught SyntaxError: Unexpected token < in JSON at position 0
的错误,当然我已经把ajaxfileupload.js
文件中的uploadHttpData:function()函数修改成一下形式了:
uploadHttpData: function( r, type ) {
var data = !type;
data = type == "xml" || data ? r.responseXML : r.responseText;
// If the type is "script", eval it in global context
if ( type == "script" )
jQuery.globalEval( data );
// Get the JavaScript object, if JSON is used.
if ( type == "json" )
//eval( "data = " + data );
data = jQuery.parseJSON(jQuery(data).text());
// evaluate scripts within html
if ( type == "html" )
jQuery("<div>").html(data).evalScripts();
return data;
}
这样依然无法解决之前的错误,甚至每次在调试到$.jsonParse()函数的时候就会跳到 ajaxFileUpload.js
文件中的这个不问来。
catch(e)
{
status = "error";
jQuery.handleError(s, xml, status, e);
}
好了,前台上传的方式说完了,下面我说一下我在后台控制器使用的方法:
首先在整个解决方案目录下建立一个文件夹,我暂且命名为Tools,然后再该文件夹下建一个.ashx的文件,然后再在同目录文件(Tools)下建立一个.ashx.cs的文件,这样我们就可以把以下的代码添加到这个cs文件中,并且在JS中调用了。
注意:这个类是要引用“IHttpHandler”接口的。
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
//上传配置
int size = 4; //文件大小限制,单位MB //文件大小限制,单位MB
string[] filetype = { ".gif", ".png", ".jpg", ".jpeg", ".bmp", ".xlsx", ".xls", ".rar", ".zip", ".doc", ".docx", ".pdf", ".txt" }; //文件允许格式
//上传图片
Hashtable info = new Hashtable();
Uploader up = new Uploader();
string path = "/UploadFile";
info = up.upFile(context, path + '/', filetype, size); //获取上传状态
string result = "{\"originalName\":\"" + info["originalName"] + "\",\"url\":\"" + info["url"] + "\"}";
//HttpContext.Current.Response.Write(result); //向浏览器返回数据json数据
context.Response.Write(result);
}
public bool IsReusable
{
get
{
return false;
}
}
然后再在同目录下(Tools)建立一个Uploader.cs文件,这个文件里面就主要写一些实现文件上传,验证筛选的函数:
public class Uploader
{
string state = "SUCCESS";
string URL = null;
string currentType = null;
string uploadpath = null;
string filename = null;
string originalName = null;
HttpPostedFile uploadFile = null;
public Hashtable upFile(HttpContext cxt, string pathbase, string[] filetype, int size)
{
uploadpath = cxt.Server.MapPath(pathbase);//获取文件上传路径
try
{
uploadFile = cxt.Request.Files[0];
originalName = uploadFile.FileName;
//目录创建
createFolder();
//格式验证
if (checkType(filetype))
{
//不允许的文件类型
state = "\u4e0d\u5141\u8bb8\u7684\u6587\u4ef6\u7c7b\u578b";
}
//大小验证
if (checkSize(size))
{
//文件大小超出网站限制
state = "\u6587\u4ef6\u5927\u5c0f\u8d85\u51fa\u7f51\u7ad9\u9650\u5236";
}
//保存
if (state == "SUCCESS")
{
filename = NameFormater.Format(cxt.Request["fileNameFormat"], originalName);
var testname = filename;
var ai = 1;
while (File.Exists(uploadpath + testname))
{
testname = Path.GetFileNameWithoutExtension(filename) + "_" + ai++ + Path.GetExtension(filename);
}
uploadFile.SaveAs(uploadpath + testname);
URL = pathbase + testname;
}
}
catch (Exception)
{
// 未知错误
state = "\u672a\u77e5\u9519\u8bef";
URL = "";
}
return getUploadInfo();
}
/**
* 按照日期自动创建存储文件夹
*/
private void createFolder()
{
if (!Directory.Exists(uploadpath))
{
Directory.CreateDirectory(uploadpath);
}
} /**
* 文件类型检测
* @return bool
*/
private bool checkType(string[] filetype)
{
currentType = getFileExt();
return Array.IndexOf(filetype, currentType) == -1;
}
/**
* 获取文件扩展名
* @return string
*/
private string getFileExt()
{
string[] temp = uploadFile.FileName.Split('.');
return "." + temp[temp.Length - 1].ToLower();
}
/**
* 文件大小检测
* @param int
* @return bool
*/
private bool checkSize(int size)
{
return uploadFile.ContentLength >= (size * 1024 * 1024);
}
/**
* 获取上传信息
* @return Hashtable
*/
private Hashtable getUploadInfo()
{
Hashtable infoList = new Hashtable();
infoList.Add("state", state);
infoList.Add("url", URL);
if (currentType != null)
infoList.Add("currentType", currentType);
if (originalName != null)
infoList.Add("originalName", originalName);
return infoList;
}
/**
* 重命名文件
* @return string
*/
private string reName()
{
return System.Guid.NewGuid() + getFileExt();
}
/**
* 删除存储文件夹
* @param string
*/
public void deleteFolder(string path)
{
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
}
}
此外,在这个Upload.cs文件下,由于需要我后期又添加了一个NameFormatter静态类:用来格式化文件名
public static class NameFormater
{
public static string Format(string format, string filename)
{
if (String.IsNullOrWhiteSpace(format))
{
format = "{filename}{rand:6}";
}
string ext = Path.GetExtension(filename);
filename = Path.GetFileNameWithoutExtension(filename);
format = format.Replace("{filename}", filename);
var invalidPattern = new Regex(@"[\\\/\:\*\?\042\<\>\|]");
format = invalidPattern.Replace(format, "");
format = Guid.NewGuid().ToString("D");
return format + ext;
}
}
最后,我将我的JS触发代码贴出来:
【 要记得引用以下JS文件,否则是无法运行的】
<script src="../content/ui/global/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="../Scripts/ajaxfileupload.js"></script>
<script src="jquery.uploadify.js"></script>
$("#uploadify").change(function () {
debugger;
var filePath = $(this).val();
loadUploadifyData(filePath);
});
function loadUploadifyData(filePath){
if (filePath.length > 0) {
$.ajaxFileUpload({
url: '../Tools/UpLoadFiles.ashx',
secureuri: false,
fileElementId: 'uploadify',
success: function (data, status) {
var test = $(data).find("pre").html();
var json = $.parseJSON(test);
console.log(json);
debugger;
var record = {
FID: '',
ATTACH_FILE: json.originalName,
ATTACH_PATH: json.url
}
AddRowAttach(record);
}
});
}
$("#uploadify").val("");
$("#uploadify").on("change", function () {
var filePath2 = $(this).val();
loadUploadifyData(filePath2);
});
}
function AddRowAttach(data){
$("#tb_attachs > tbody").append('<tr name="tr_attach">'
+ '<td><a href="' + data.ATTACH_PATH + '" target="view_window">' + data.ATTACH_FILE + '</a><input type="hidden" name="AttachId" value="' + data.FID + '"><input type="hidden" name="AttachName" value="' + data.ATTACH_FILE + '"><input type="hidden" name="AttachPath" value="' + data.ATTACH_PATH + '"></td>'
+ '<td><div title="' + data.FID + '" name="' + data.ATTACH_PATH + '"onclick=" (this);" style="background: url(/content/ui/img/blog/uploadify-cancel.png) no-repeat;width:20;height:20px;cursor:pointer;"></div></td>'
+ '</tr>')
}
*希望各位博友看见,有什么不懂的地方我们可以一起交流,甚至我有些地方可能理解错误,希望能有好心的博友向我提出来哦~
联系方式:QQ:614592781*