导航
  • 主页
  • ASP
  • .NET Framework
  • Web Services
  • VB
  • VC
  • 图表区
  • 分析与设计
  • 组件/控件开发
  • LINQ
  • 问答

Asp.net上传

bhtfg538 2008-06-26 11:05:27
我新 手·
最近涉及到Asp.net上传
我知道有 FileUploadweb控件。
当然我还是担心安全方面的问题 原来我使用asp 是自己写的组件
今天写了个类
不知道有没有必要,也是一时兴起。主要方便以后经常使用 省得复制代码
朋友们多帮我看看~ 或者有 什么好的上传类 发给我 贴出来
我的 邮箱:beyondmj0.student@sina.com
我的代码:

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Services.Description;

/// <summary>
///fileupload 的摘要说明
/// </summary>
public class fileupload
{
private int FileSize;//默认文件大小
private string FilePath;//默认文件路径
private string FileName;//默认文件名字
private string[] FileFormat;//默认文件格式
private string ErrorMsg;//默认错误信息
private string[] FileType;//默认文件MINE类型
private int UploadFileSize;
private string UploadFileName;
private string UploadFilePath;
public fileupload()
{
FileSize = 20480;//2mb
FilePath = @"C:\Inetpub\wwwroot\upload\";
FileName = Regex.Replace(DateTime.Now.ToString(), "( |:|-|上午|下午)", "");
FileFormat = new string[] { "jpg", "jpeg", "gif", "png","bmp"};
FileType = new string[] { "image" };
ErrorMsg = null;
}
public string Msg
{
get
{
return ErrorMsg;
}
set
{
ErrorMsg = value;
}
}
public int GetSize
{
get
{
return UploadFileSize;
}

}
public string GetName
{
get
{
return UploadFileName;
}

}
public string GetPath
{
get
{
return UploadFilePath;
}

}

public fileupload(int size, string path, string[] format,string[] type)
{
FileSize = size;
FilePath = path;
FileFormat = format;
FileType = type;
}
public fileupload(string path)
{
FilePath = path;
}
public bool FileUpload(FileUpload fu)
{
string CurrentFileName = fu.FileName.Trim();//取得当前文件名字
string CurrentFullName = fu.PostedFile.FileName.Trim();//取得当前文件整个名字
int CurrentFileSize = fu.PostedFile.ContentLength;//取得当前文件大小
string CurrentFileType = fu.PostedFile.ContentType.Trim();//取得当前文件MINE类型
StringBuilder sb=new StringBuilder();//返回字符串式的文件类型
int ffl = FileFormat.Length;//文件格式的数组长度
int fnl = CurrentFileName.Split('.').Length;//返回文件名数组的长度
string[] cfns=CurrentFileName.Split('.');//返回文件名字的数组
int ftl=FileType.Length;//返回Mine数组的长度
StringBuilder sb1=new StringBuilder();//返回Mine数组字符串
for(int i=0;i<ftl;i++)
{
if(i< ftl - 1)
{
sb1.Append(FileType[i].ToString().Trim()+"|");
}
else
{
sb1.Append(FileType[i].ToString().Trim());
}
}
for (int i = 0; i < ffl; i++)
{
if (i < ffl - 1)
{
sb.Append(FileFormat[i].ToString().Trim()+"|");
}
else
{
sb.Append(FileFormat[i].ToString().Trim());
}

}
Regex reg = new Regex(@"^[a-z]\:\\([^""\.\\\<\>\:\/\?\|][^""\\\<\>\:\/\?\|]+[^""\.\\\<\>\:\/\?\|]\\)*[^""\\\<\>\:\/\?\|]+\.(" + sb.ToString() + ")$", RegexOptions.IgnoreCase);
try
{
if (fnl < 2)
{
Msg = "你上传的文件名出现错误。<br>";
return false;
}
else
{
if (sb.ToString().IndexOf(cfns[fnl-1].ToString().Trim().ToLower()) >= 0 || sb.ToString().IndexOf(cfns[fnl-1].ToString().Trim().ToUpper()) >= 0)
{
if (!reg.Match(CurrentFullName).Success)
{
Msg = Msg + "你上传的文件路径出现错误。<br>";
return false;
}
else
{

if (CurrentFileSize > FileSize)
{
Msg = Msg + "上传文件超过系统默认大小," + "当前文件大小:" + (float)(CurrentFileSize/1024)+ "KB,系统默认大小:" + (float)(FileSize/1024)+"KB。<br>";
return false;
}
else
{
if (CurrentFileType.Split('/').Length>0)
{
if (sb1.ToString().IndexOf(CurrentFileType.Split('/')[0].ToString().Trim().ToLower()) >= 0)
{
string filename = FileName + "." + cfns[1];
UploadFileSize = CurrentFileSize;
UploadFileName = filename;
UploadFilePath = FilePath;

fu.PostedFile.SaveAs(FilePath + filename);
return true;

}
else
{
Msg = Msg + "上传文件MIME类型错误,你的MIME类型为:"+CurrentFileType+"。<br>";
return false;
}
}
else
{
Msg = Msg + "上传文件MIME类型错误,你的MIME类型为:" + CurrentFileType + "。<br>";
return false;
}
}
}
}
else
{
Msg = "文件类型不正确,不能为:“" + cfns[fnl - 1] + "”的后缀名,系统默认文件类型为:" + sb.ToString().Replace('|', ',') + "。<br>";
return false;
}
}
}
catch (Exception ex)
{
Msg = Msg+ex.Message;
return false;
}

}

}


...全文
200 点赞 收藏 32
写回复
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
yigeming 2008-06-27
[Quote=引用 20 楼 s208ping 的回复:]
C# codeusing System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Text;
using System.Web;
using System.Reflection;
public class HttpUploadModule : IHttpModule
{
private HttpApplication hApp;
public HttpUploadModule()
{

}
public int nState;
public void …
[/Quote]
回复
simson2010 2008-06-27
能支持Web上传多大的文件
回复
david0620 2008-06-27
支持大文件上傳不咯?例如1G的文件
回复
stning 2008-06-27
个人觉得20楼的比较好。
回复
sxmonsy 2008-06-27
楼主很强,帮你顶下.
回复
s208ping 2008-06-27
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Text;
using System.Web;
using System.Reflection;
public class HttpUploadModule : IHttpModule
{
private HttpApplication hApp;
public HttpUploadModule()
{

}
public int nState;
public void Init(HttpApplication application)
{
hApp = application;
application.BeginRequest += new EventHandler(this.Application_BeginRequest);
application.EndRequest += new EventHandler(this.Application_EndRequest);
application.Error += new EventHandler(this.Application_Error);
nState = 1;
}

public void Dispose()
{
}

private void Application_BeginRequest(Object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
HttpWorkerRequest request = GetWorkerRequest(app.Context);
Encoding encoding = app.Context.Request.ContentEncoding;

int bytesRead = 0; // 已读数据大小
int read; // 当前读取的块的大小
int count = 8192; // 分块大小
byte[] buffer; // 保存所有上传的数据
string uploadId; // 唯一标志当前上传的ID
Progress progress; // 记录当前上传的进度信息

if (request != null)
{

// 返回 HTTP 请求正文已被读取的部分。
//
byte[] tempBuff = request.GetPreloadedEntityBody();
// 如果是附件上传
//
if (tempBuff != null && IsUploadRequest(app.Request))
{
// 当前上传的ID,用来唯一标志当前的上传
// 用此UploadID,可以通过其他页面获取当前上传的进度
if (app.Context.Request.Cookies["UploadID"] == null)
{
HttpCookie hCookie = new HttpCookie("UploadID");
hCookie.Value = Guid.NewGuid().ToString();
app.Context.Response.Cookies.Add(hCookie);
}
uploadId = app.Context.Request.Cookies["UploadID"].Value.ToString();

long length = long.Parse(request.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength));
//判断文件大小,超出了就不传
System.Xml.XmlDocument xml = new System.Xml.XmlDocument();
xml.Load(app.Context.Server.MapPath("~/web.config"));
System.Xml.XmlNode node = xml.SelectSingleNode("configuration/system.web/httpRuntime");
long nMaxLength = Convert.ToInt64(node.Attributes["maxRequestLength"].Value) * 1024;
if (length > nMaxLength)
{
Fish.common.MessageBox("上传文件超出最大值,系统最大允许" + Fish.common.ConvertByte(nMaxLength), false);
nState = -1;
Application_EndRequest(sender, e);
Fish.common.GoUrl(app.Context.Request.ServerVariables["http_referer"]);
}
// 获取上传大小
//
//将数据保存到文件里
using(FileStream fs = File.Open(app.Context.Server.MapPath(uploadId + ".tmp"), FileMode.OpenOrCreate))
{
// 将已上传数据复制过去
fs.Write(tempBuff, 0, tempBuff.Length);

// 开始记录当前上传状态
//
progress = new Progress(length, uploadId);
progress.SetState(UploadState.ReceivingData);

//buffer = new byte[length];
count = tempBuff.Length; // 分块大小

// 开始记录已上传大小
//
bytesRead = tempBuff.Length;
progress.SetBytesRead(bytesRead);
SetProgress(uploadId, progress, app.Application);

// 循环分块读取,直到所有数据读取结束
//
//测试 恢复count
//count = 1;
while (request.IsClientConnected() && !request.IsEntireEntityBodyIsPreloaded() && bytesRead < length)
{
// 如果最后一块大小小于分块大小,则重新分块
//
if (bytesRead + count > length)
{
count = (int)(length - bytesRead);
tempBuff = new byte[count];
}

// 分块读取
//
read = request.ReadEntityBody(tempBuff, count);

// 复制已读数据块
//
//----Buffer.BlockCopy(tempBuff, 0, buffer, bytesRead, read);
fs.Write(tempBuff, 0, read);
// 记录已上传大小
//
bytesRead += read;
progress.SetBytesRead(bytesRead);
SetProgress(uploadId, progress, app.Application);

}
if (request.IsClientConnected() && !request.IsEntireEntityBodyIsPreloaded())
{

// 传入已上传完的数据
//
fs.Close();
fs.Dispose();
FileStream fRead = File.Open(app.Context.Server.MapPath(uploadId + ".tmp"), FileMode.Open);

buffer = new byte[fRead.Length];
int nLen = fRead.Read(buffer, 0, (int)fRead.Length);
fRead.Close();
fRead.Dispose();
InjectTextParts(request, buffer);
buffer = null;
// 表示上传已结束
//
progress.SetBytesRead(bytesRead);
progress.SetState(UploadState.Complete);
SetProgress(uploadId, progress, app.Application);

}
//删除文件
tempBuff = null;
fs.Close();
fs.Dispose();
}
File.Delete(app.Context.Server.MapPath(uploadId + ".tmp"));
}
}
}

/// 结束请求后移除进度信息
private void Application_EndRequest(Object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;

if (IsUploadRequest(app.Request) && nState > 0)
{
SetUploadState(app, UploadState.Complete);
RemoveFrom(app);
}

}
/// 如果出错了设置进度信息中状态为“Error”
private void Application_Error(Object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;

if (IsUploadRequest(app.Request) && nState > 0)
{
SetUploadState(app, UploadState.Error);
}

}

/// 设置当前上传进度信息的状态
void SetUploadState(HttpApplication app, UploadState state)
{
string uploadId = app.Context.Request.Cookies["UploadID"].ToString();
if (uploadId != null && uploadId.Length > 0)
{
Progress progress = GetProgress(uploadId, app.Application);
if (progress != null)
{
progress.SetState(state);
SetProgress(uploadId, progress, app.Application);
}
}
}

/// 设置当前上传的进度信息
/// 根据UploadID记录在Application中
void SetProgress(string uploadId, Progress progress, HttpApplicationState application)
{
if (uploadId == null || uploadId == string.Empty || progress == null)
return;
application.Lock();
application["Fish_" + uploadId] = progress;
application.UnLock();
}

/// <summary>
/// 从Application中移出进度信息
/// </summary>
/// <param name="app"></param>
void RemoveFrom(HttpApplication app)
{
string uploadId = app.Context.Request.Cookies["UploadID"].Value.ToString();
HttpApplicationState application = app.Application;
if (uploadId != null && uploadId.Length > 0)
{
application.Remove("Fish_" + uploadId);
app.Context.Request.Cookies.Remove("UploadID");
}
}
/// 根据UploadID获取上传进度信息
public static Progress GetProgress(string uploadId, HttpApplicationState application)
{
Progress progress = application["Fish_" + uploadId] as Progress;
return progress;
}

HttpWorkerRequest GetWorkerRequest(HttpContext context)
{

IServiceProvider provider = (IServiceProvider)HttpContext.Current;
return (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));
}
/// 传入已上传完的数据
void InjectTextParts(HttpWorkerRequest request, byte[] textParts)
{
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;

Type type = request.GetType();

while ((type != null) && (type.FullName != "System.Web.Hosting.ISAPIWorkerRequest"))
{
type = type.BaseType;
}

if (type != null)
{
type.GetField("_contentAvailLength", bindingFlags).SetValue(request, textParts.Length);
type.GetField("_contentTotalLength", bindingFlags).SetValue(request, textParts.Length);
type.GetField("_preloadedContent", bindingFlags).SetValue(request, textParts);
type.GetField("_preloadedContentRead", bindingFlags).SetValue(request, true);
}
}

private static bool StringStartsWithAnotherIgnoreCase(string s1, string s2)
{
return (string.Compare(s1, 0, s2, 0, s2.Length, true, CultureInfo.InvariantCulture) == 0);
}
/// 是否为附件上传
bool IsUploadRequest(HttpRequest request)
{
return StringStartsWithAnotherIgnoreCase(request.ContentType, "multipart/form-data");
}
}

回复
有许多开源项目,有文件管理的
回复
fellowcheng 2008-06-27
不如直接用前台:html + 后台:HttpFileCollection 实现,可以同时选择多个文件


//添加附件控件
function addFile(addNew)
{
var trAtt = document.getElementById("trAtt");
trAtt.style.display = "";
if(addNew)
{
var tdAttachment = document.getElementById("attachmentId");
if(tdAttachment)
{
var oDiv = document.createElement('div');
tdAttachment.appendChild(oDiv);
var oFile = document.createElement('<input type="file" size="50" name="File" runat="server" >');
oDiv.appendChild(oFile);
var oButton = document.createElement('<button onclick="removeme()">');
oButton.innerHTML = '删除';
oDiv.appendChild(oButton);

// document.getElementById("appendLink").alt = '继续添加附件';
}
}
}




/// <summary>
/// 保存新加附件
/// </summary>
/// <returns></returns>
private void SaveAttachment()
{
try
{
string strPath = ConfigurationManager.AppSettings["UploadFilesPath"];
string RootPath = Server.MapPath(strPath + "/CorpRules/" + User.Identity.Name + "/");
string virtualPath = "/CorpRules/" + User.Identity.Name + "/";
if (!Directory.Exists(RootPath))
{
Directory.CreateDirectory(RootPath);
}
HttpFileCollection fileList = HttpContext.Current.Request.Files;
for (int i = 0; i < fileList.Count; i++)
{
HttpPostedFile file = fileList[i];
string fileN = file.FileName.Substring(file.FileName.LastIndexOf("\\") + 1);
string fileName = RootPath + "\\" + fileN;

if (file.ContentLength > 0)
{
fileName = CheckFileName(fileName);
file.SaveAs(fileName);

int fileSize = file.ContentLength / 1024;

CorpRulesAttachment entTmp = (CorpRulesAttachment)Weith.Toolkit.Reflection.TypeAccessor.CreateInstance(typeof(CorpRulesAttachment));
entTmp.CorpRulesAttachmentID = Guid.NewGuid();
entTmp.Path = virtualPath + fileN;
entTmp.Size = fileSize;
attList.Add(entTmp);
}
}
}
catch (Exception)
{
DelFiles();
Response.Redirect("~\\Error\\ServerError.aspx");
}
}
回复
大自然D使者 2008-06-27
没做过这么复杂,都是先用先写,反正就几行代码,又不多。
回复
bhtfg538 2008-06-27
饿。。。没准看 明白还不会做控件
回复
industrial 2008-06-27
楼上的这个控件是WroxUnited的吧:)
回复
城市猎人0611 2008-06-27
做成一个控件:PictureUpload.ascx
<%@ Control Language="C#" AutoEventWireup="true" codefile="PictureUpload.ascx.cs" inherits="PictureUpload" %>
<asp:FileUpload ID="FileUpload1" Runat="server" />
<asp:Button ID="btnUpload" Runat="server" Text="Upload Picture" OnClick="btnUpload_Click"
Width="127px" Height="21px" />
<asp:Label ID="Status" Runat="server"></asp:Label>

PictureUpload.ascx.cs文件:
using System;
using System.IO;
partial class PictureUpload : System.Web.UI.UserControl
{
// the class to return to the calling page
// - it simply contains the relative path of where the file was uploaded
public class FileUploadEventArgs : EventArgs
{
public FileUploadEventArgs(string FileName)
{
_fileName = FileName;
}

private string _fileName;
public string FileName
{
get {return _fileName;}
}
}
// define the delgate for the sucessful uploading event
public delegate void FileUploadedEventHandler( object sender, FileUploadEventArgs e);
// define the event for sucessful upload
public event FileUploadedEventHandler FileUploaded;
// the modes for uploading images
public enum ImageType
{
Match,
News,
Player,
Product
}
private ImageType _uploadImageType;
public ImageType UploadImageType
{
get {return _uploadImageType;}
set {_uploadImageType = value;}
}
protected void btnUpload_Click(object sender, System.EventArgs e)
{
string ImagesFolder = string .Empty;
string savePath;
string saveFile;

// upload the file
if (FileUpload1.HasFile)
{
// set the directories
switch (_uploadImageType)
{
case ImageType.Match:
ImagesFolder = "MatchImages";
break;
case ImageType.News:
ImagesFolder = "NewsImages";
break;
case ImageType.Player:
ImagesFolder = "PlayerImages";
break;
case ImageType.Product:
ImagesFolder = "ProductImages";
break;
}
savePath = Path.Combine(Request.PhysicalApplicationPath, ImagesFolder);

// save the image
saveFile = Path.Combine(savePath, FileUpload1.FileName);
FileUpload1.SaveAs(saveFile);

// for product images we also create a thumbnail
if (_uploadImageType == ImageType.Product)
{
string newPath = Path.Combine(savePath, "thumb_" + FileUpload1.FileName);
ImageHandling.GenerateThumbnail(saveFile, newPath);
}

// Notify the user that the file was uploaded successfully.
Status.Text = "Your file was uploaded successfully.";

// let the parent know that the file was uploaded
OnFileUploaded(new FileUploadEventArgs(FileUpload1.FileName));
}
else
{
// Notify the user that a file was not uploaded.
Status.Text = "You did not specify a file to upload.";
}
}
// declare the event method
protected virtual void OnFileUploaded( FileUploadEventArgs e)
{
// fire the delegate
FileUploaded(this, e);
}
}
回复
bhtfg538 2008-06-27
顺便太提问下
如果对方刷新下
又上传了一个

session 和 cookie 可以解决
有没有 其他好办法呢?

在 Ispostback 里面做做手脚


回复
bhtfg538 2008-06-27
思路是通过 正则匹配文件
而文件名字是通过正则匹配的

大家 你自己测试下
使用很简单 帮我检查有没 bug
回复
bhtfg538 2008-06-27
[Quote=引用 9 楼 iuhxq 的回复:]
DateTime.Now.ToString("yyyyMMddHHmmss")
[/Quote]谈感谢了
可以这样格式化字符
谢谢


大家有好的 类 共享出来哈


星际
玩了好多年了
现在 属于小强级别
呵呵 ~
回复
tinalucky 2008-06-27
有点晕~~
回复
iuhxq 2008-06-27
DateTime.Now.ToString("yyyyMMddHHmmss")


回复
huming_h 2008-06-27
看得出楼主比较喜欢星际争霸
回复
huming_h 2008-06-27
jf.
回复
lzqlrr 2008-06-27
mark ,study
回复
发动态
发帖子
.NET技术社区
创建于2007-09-28

5.8w+

社区成员

.NET技术交流专区
申请成为版主
社区公告
暂无公告