多图片上传代码。使用js,ICallbackEventHandler和ashx。
在ie5.5,ie8和firefox2.0.0.12下可用。
参考:http://www.codeproject.com/KB/ajax/AJAXUpload.aspx?display=Mobile
1. 创建自定义控件UpLoadPic.ascx
1.1 添加以下代码:
<input id="File1" runat="server" οnchange="PopulateListPic(this)" type="File" contenteditable="false"/>
<input type="hidden" id="list" runat="server" />
<div id="fileList" runat="server"></div>
1.2. 使用ICallbackEventHandler将图片上传到服务器。
1.2.1 实现ICallbackEventHandler接口
public partial class UpLoadPic : System.Web.UI.UserControl, ICallbackEventHandler
1.2.2 声明变量returnValue,供UpLoadPic.ascx.cs的方法调用。
Chrome下因为安全设置,returnValue在上传后值为C:\fakepath,所以出错。
protected string returnValue = String.Empty;
1.2.3 Page_Load事件中,
string sbReference = this.Parent.Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
string cbScript = String.Empty;
if (!this.Parent.Page.ClientScript.IsClientScriptBlockRegistered("CallServer"))
{
cbScript = @" function CallServer(arg,context) { " + sbReference + "}";
this.Parent.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", cbScript, true);
}
1.2.4 实现ICallbackEventHandler接口的两个方法
public string GetCallbackResult()
{
if (IsImage(returnValue) && IsSmall(returnValue))//判断是否为图片类型以及图片大小
{
//文件名
Random rnd = new Random();
string fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + rnd.Next() + System.IO.Path.GetExtension(returnValue);
//文件夹
string path = Server.MapPath("~/Adpic/") + DateTime.Now.ToString("yyyyMM") + "/";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string fullPath = path + fileName;
Stream s = File.OpenRead(returnValue);
byte[] buffer = new byte[s.Length];
s.Read(buffer, 0, (int)s.Length);
int len = (int)s.Length;
s.Dispose();
s.Close();
FileStream fs = new FileStream(fullPath, FileMode.Create);
fs.Write(buffer, 0, len);
fs.Dispose();
fs.Close();
//添加一条记录到数据库UpLoadImage表中
return "../Adpic/" + DateTime.Now.ToString("yyyyMM") + "/" + fileName;
}
return "";
}
public void RaiseCallbackEvent(string eventArgument)
{
if (!String.IsNullOrEmpty(eventArgument))
{
returnValue = eventArgument;
}
}
1.2.5 加入文件类型及大小的判断
protected bool IsImage(string returnValue)//图片类型
{
FileStream fs = new System.IO.FileStream(returnValue, System.IO.FileMode.Open, System.IO.FileAccess.Read);
BinaryReader r = new System.IO.BinaryReader(fs);
string fileclass = "";
byte buffer;
buffer = r.ReadByte();
fileclass = buffer.ToString();
buffer = r.ReadByte();
fileclass += buffer.ToString();
r.Close();
if (fileclass == "255216" || fileclass == "7173" || fileclass == "6677" || fileclass == "13780" || fileclass == "6787")//jpg gif bmp png swf
return true;
return false;
}
protected bool IsSmall(string returnValue)//大小
{
FileStream fs = new System.IO.FileStream(returnValue, System.IO.FileMode.Open, System.IO.FileAccess.Read);
if (fs.Length > 102400)
return false;
return true;
}
2. 创建uploadpic.js文件
2.1 声明全局变量
var counter = 1;//图片数目
var newPath = '';//图片在服务器上保存的路径
var filePath = '';//本地路径
2.2 实现PopulateList函数
function PopulateList(obj)
{
if(counter<6)
{
filePath = obj.value;
CallServer(obj.value,'');
}
else
{
alert("可上传图片最多为5张!");
}
}
2.3 实现ReceiveServerData函数
function ReceiveServerData(rValue)
{
newPath = rValue;
if(newPath!='')
CreateNestedElementsPic();
else
alert("上传文件不是图片或图片超出100KB,请重新上传!");
}
2.4 显示图片及创建删除按钮
function CreateNestedElements()
{
var obj = document.getElementById("UpLoadPic_fileList");
var divElement = document.createElement('div');
divElement.id = 'div' + counter;
var deleteButton = document.createElement('button');
deleteButton.value = 'Delete';
deleteButton.innerHTML = 'Delete';
deleteButton.id='add';
deleteButton.onclick =DeleteItem;
var imageObject = document.createElement('img');
imageObject.src = newPath;
divElement.appendChild(imageObject);
divElement.appendChild(deleteButton);
document.getElementById("UpLoadPic_fileList").appendChild(divElement);
counter++;
}
2.5 删除图片
如果图片是在添加信息页面中添加的,或在编辑页面中新添加的,移除图片及删除按钮的显示,并调用ashx(删除服务器上的图片以及修改相关记录)
如果图片是在编辑页面中原本已存在的,只移除图片及删除按钮的显示。
这里使用id来记录,不是很好,但没出错。
function DeleteItem(e)
{
var evt = e || window.event;
var evtTarget = evt.target || evt.srcElement;
if(evtTarget.parentElement)
var childDiv = evtTarget.parentElement;
// FIREFOX
else if(evtTarget.parentNode)
var childDiv = evtTarget.parentNode;
if(evtTarget.id=='add')
{
var index1 = childDiv.innerHTML.indexOf("src",0);
var index2 = childDiv.innerHTML.indexOf("\"");
var index3 = childDiv.innerHTML.indexOf("\"",index2+1);
var qry="../Controls/DeletePicture.ashx?pathandname="+childDiv.innerHTML.substr(index1+14,index3-index1-14);
if(window.XMLHttpRequest)
var xmlhttp =new XMLHttpRequest();
else
var xmlhttp = new ActiveXObject("MSXML2.XMLHTTP.5.0");//Microsoft.XMLHTTP
xmlhttp.open("GET",qry,false);
xmlhttp.setRequestHeader("Content-Type", "text/xml");
xmlhttp.send(qry);
if(xmlhttp.status==200)
{
// IE
if(evtTarget.parentElement)
childDiv.parentElement.removeChild(childDiv);
// FIREFOX
else if(evtTarget.parentNode)
childDiv.parentNode.removeChild(childDiv);
counter--;
}
}
if(evtTarget.id=='edit')
{
if(evtTarget.parentElement)
childDiv.parentElement.removeChild(childDiv);
// FIREFOX
else if(evtTarget.parentNode)
childDiv.parentNode.removeChild(childDiv);
counter--;
}
}
2.6 保存信息的同时为UpLoadPic_list赋值,值为上传到服务器上的图片的路径之和。格式为:路径1|路径2|...
function SavePic()
{
document.getElementById("UpLoadPic_list").value = "";
var path = '';
var divObject = document.getElementById("UpLoadPic_fileList");
var divChilds = divObject.childNodes;
for(i=0; i<divChilds.length; i++)
{
var path = divChilds[i].innerHTML;
var index1 = path.indexOf("src",0);
var index2 = path.indexOf("\"");
var index3 = path.indexOf("\"",index2+1);
document.getElementById("UpLoadPic_list").value += path.substr(index1+14,index3-index1-14);
document.getElementById("UpLoadPic_list").value += "|";
}
}
2.7 如果控件在编辑信息页面中使用,则需要调用以下函数,在页面初始化时显示图片及删除按钮
function CreateNestedElementsForEdit(newPath)
{
var obj = document.getElementById("UpLoadPic_fileList");
var divElement = document.createElement('div');
divElement.id = 'div' + counter;
var deleteButton = document.createElement('button');
deleteButton.value = 'Delete';
deleteButton.innerHTML = 'Delete';
deleteButton.id='edit';
deleteButton.onclick = DeleteItem;
var imageObject = document.createElement('img');
imageObject.src = "adpic/"+newPath;
divElement.appendChild(imageObject);
divElement.appendChild(deleteButton);
document.getElementById("UpLoadPic_fileList").appendChild(divElement);
counter++;
}
3. 创建DeletePicture.ashx,进行服务器端的更新(更新UploadImage数据表记录,设置IsUsed为0,并删除服务器上的图片)。
4. 调用用户控件UpLoadPic.ascx。
保存信息时获取图片路径代码为:
((HtmlInputHidden)UpLoadPic.FindControl("list")).Value
5. 多图片上传控件在添加修改信息页面中使用。
思路:
使用表UpLoadImage的IsUsed字段存储图片的使用状态。
添加信息时:
选择某个图片以后立即将其上传到服务器,并在UpLoadImage表中添加一条相应的记录,IsUsed为0。
点击某图片后面删除按钮后直接删除服务器上的图片,并将UpLoadImage表中相应的记录的IsUsed设置为0。
点击信息保存按钮,将UpLoadImage表中相应的所有记录的IsUsed设置为1。
修改信息时:
选择某个图片以后立即将其上传到服务器,并在UpLoadImage表中添加一条相应的记录,IsUsed为0。
点击某图片删除按钮后不删除服务器上的图片,也不从UpLoadImage表中删除相应的记录。
保存信息时,将UpLoadImage表中相应的所有记录(包括保存信息前和保存信息后的图片)的IsUsed设置为0或1,并删除为0的记录对应的图片。
删除信息时:
将UpLoadImage表中相应的所有记录的IsUsed设置为0,并删除图片。
(这是以前写的代码,根据已有的ASP改为ASP.Net,所以图片删除时UpLoadImage表中的相应记录的IsUsed设置为0。可能删除此记录比较好。
如果在删除图片的时候删除相应的记录,那么只在一种情况下,图片在数据表中IsUsed值为0:上传图片后未保存信息。)