当前位置:编程学习 > C#/ASP.NET >>

uploadify的asp.NET图片上传并处理session丢失的解决方案

插件在asp教程.net网站中的一个应用实例,希望对大家有所帮助,写得有什么不妥的地方也希望大家能够指出和见谅(这是在下技术博客中的易做图作)。好了,以下就是该插件的主要使用方法。

<title>uploadify -- 示例</title>
 
<script type="text/网页特效" src="uploader/jquery-1.4.1.min.js" kesrc="uploader/jquery-1.4.1.min.js"></script>
 
<script type="text/javascript" src="uploader/jquery.uploadify.v2.1.0.min.js" kesrc="uploader/jquery.uploadify.v2.1.0.min.js"></script>
 
<script type="text/javascript" src="uploader/swfobject.js" kesrc="uploader/swfobject.js"></script>
 
<link type="text/css教程" href="uploader/uploadify.css" kesrc="uploader/uploadify.css" rel="stylesheet">
<style type="text/css">
.wrapper{ width:400px; margin:10px auto}
</style>
 
<form id="form1" runat="server">
    <div class="wrapper">
        <b>uploadify 示例程序</b>
        <div id="fileinput1">
        </div>
        <a href="javascript:$('#fileinput1').uploadifyupload()" kesrc="javascript:$('#fileinput1').uploadifyupload()">上传</a> | <a href="javascript:$('#fileinput1').uploadifyclearqueue()" kesrc="javascript:$('#fileinput1').uploadifyclearqueue()">
            取消上传</a>
    </div>
 
    <script type="text/javascript">
    $("#fileinput1").uploadify({
        'uploader': 'uploader/uploadify.swf',
        'method': 'get',
        'script': 'uploadfile.aspx',
        'cancelimg': 'uploader/cancel.png',
        'auto': false,
        'multi': true,
    });
    </script>
 
</form>

flash的,因此我们用swfobject.js来处理flash,swfobject是一个用于在html中方面插入adobe flash媒体资源(*.swf文件)的独立、敏捷的javascript模块。该模块中的javascript脚本能够自动检测pc、mac机器上各种主流浏览器对flash插件的支持情况。它使得插入flash媒体资源尽量简捷、安全。而且它是非常符合搜索引擎优化的原则的。此外,它能够避免您的 html、xhtml中出现object、embed等非标准标签,从而符合更加标准

 

public partial class uploadfile : system.web.ui.page
{
    protected void page_load(object sender, eventargs e)
    {
        try
        {
            //获取上传的文件数据
            httppostedfile file = request.files["filedata"];    
            string filename = file.filename;
            //由于不同浏览器取出的filename不同(有的是文件绝对路径,有的是只有文件名),故要进行处理
            if (filename.indexof('') > -1)    
            {
                filename = filename.substring(filename.lastindexof('') + 1);
            }
            else if (filename.indexof('/') > -1)
            {
                filename = filename.substring(filename.lastindexof('/') + 1);
            }
            //上传的目录
            string uploaddir = "~/files/";
            //上传的路径
            string uploadpath = uploaddir + guid.newguid() + filename;
            //保存文件
            file.saveas(server.mappath(uploadpath));
            //下面这句代码缺少的话,上传成功后上传队列的显示不会自动消失
            response.write("1");
        }
        catch
        {
            response.write("0");
        }
    }
}

原来一般情况下,因为诸如uploadify,swfupload采用的都是flash客户端,这样它们产生的useragent与用户使用浏览器的 user-agent必然不同。所以,虽然用户登录了你的系统产生了一个session,但是当触发上传程序时会产生另一个session(在上述 useragent选项开启的情况下)。所以,不是session丢失了,而是当你上传文件时,ci为uploadify另外创建了一个session。好了,既然找到问题的根源,我们就想办法让服务器在session判空之前将session值手动传递过去。

在asp.net教程中的解决方案如下:

在上传的那个页面中加入以下代码

var auth = "<% = request.cookies[formsauthentication.formscookiename]==null ? string.empty : request.cookies[formsauthentication.formscookiename].value %>";
var asps教程essid = "<%= session.sessionid %>";

然后初始化插件的代码改成如下形式

$("#fileinput1").uploadify({
            'uploader': '/scripts/uploader/uploadify.swf',
            'method': 'get',
            'script': '/mystudio/gouploadavatar',
            'cancelimg': '/scripts/uploader/cancel.png',
            'sizelimit': 2048000,
            'multi': false,
            'filedesc': '选择jpg,png,gif',
            'fileext': '*.jpg;*.png;*.gif',
 
            'oncomplete': function (e, queueid, fileobj, response, data) {
 
            },
           'onselectonce': function (e, data) {
                $('#fileinput1').uploadifysettings('scriptdata', { 'aspsessid': aspsessid, 'authid': auth });
            }
 });

注意上面有一句,很关键

$('#fileinput1').uploadifysettings('scriptdata', { 'aspsessid': aspsessid, 'authid': auth });

接下来我们必须在服务端session判空并创建之前,将传递过来的sessonid强制赋给当前请求的cookies,这样服务端就认为还是原来的session传递过来了。具体做法我们可以在global.asax文件中加入如下代码

protected void application_beginrequest(object sender, eventargs e)
        {
            /* we guess at this point session is not already retrieved by application so we recreate cookie with the session id... */
            try
            {
                string session_param_name = "aspsessid";
                string session_cookie_name = "asp.net_sessionid";

                if (httpcontext.current.request.form[session_param_name] != null)
                {
                    updatecookie(session_cookie_name, httpcontext.current.request.form[session_param_name]);
                }
                else if (httpcontext.current.request.querystring[session_param_name] != null)
                {
                    updatecookie(session_cookie_name, httpcontext.current.request.querystring[session_param_name]);
                }
            }
            catch
            {
            }

            try
            {
                string auth_param_name = "authid";
                string auth_cookie_name = formsauthentication.formscookiename;

                if (httpcontext.current.request.form[auth_param_name] != null)
                {
                    updatecookie(auth_cookie_name, httpcontext.current.request.form[auth_param_name]);
                }
                else if (httpcontext.current.request.querystring[auth_param_name] != null)
                {
                    updatecookie(auth_cookie_name, httpcontext.current.request.querystring[auth_param_name]);
                }

            }
            catch
            {
            }
        }

        private void updatecookie(string cookie_name, string cookie_value)
        {
            httpcookie cookie = httpcontext.current.request.cookies.get(cookie_name);
            if (null == cookie)
            {
                cookie = new httpcookie(cookie_name);
            }
            cookie.value = cookie_value;
            httpcontext.current.request.cookies.set(cookie);
        }

这时候你访问上传文件的那个页面时可能会报“会话状态已创建一个会话 id,但由于响应已被应用程序刷新而无法保存它”的错误,这时,你可以在web.config文件改变session的存储方式,一般默认都是以 “inproc”存储的,我们把它改成stateserver模式,即在system.web节点下加入

<sessionstate mode="stateserver" stateconnectionstring="tcpip=127.0.0.1:42424" timeout="30"></sessionstate>

ok,问题解决,虽然看起来解决这个问题比较麻烦(不知道在其他网站中怎么弄,至少在.net中比较麻烦),但这么好的一个文件上传插件,这样做很值得

 


基于jquery+flash的多文件上传插件uploadify,暂且不具体介http://www.uploadify.com/demos/绍,先来看看效果图吧。


怎么样,效果不错吧,既支持多文件上传,又能有进度提示,给用户非常好的体验,而且这是一个开源项目,大家可以在自己的项目中自由的使用和修改。
项目主页地址:http://www.uploadify.com/    插件演示地址:http://www.uploadify.com/demos/
插件下载地址:http://www.uploadify.com/download/   插件使用文档:http://www.uploadify.com/documentation/


好了关于一些常用参数

uploader : uploadify.swf 文件的相对路径,该swf文件是一个带有文字browse的按钮,点击后淡出打开文件对话框,默认值:uploadify.swf。
script :   后台处理程序的相对路径 。默认值:uploadify.php教程
checkscript :用来判断上传选择的文件在服务器是否存在的后台处理程序的相对路径
filedataname :设置一个名字,在服务器处理程序中根据该名字来取上传文件的数据。默认为filedata
method : 提交方式post 或get 默认为post
scriptaccess :flash脚本文件的访问模式,如果在本地测试设置为always,默认值:samedomain 
folder :  上传文件存放的目录 。
queueid : 文件队列的id,该id与存放文件队列的div的id一致。
queuesizelimit : 当允许多文件生成时,设置选择文件的个数,默认值:999 。
multi : 设置为true时可以上传多个文件。
auto : 设置为true当选择文件后就直接上传了,为false需要点击上传按钮才上传 。
filedesc : 这个属性值必须设置fileext属性后才有效,用来设置选择文件对话框中的提示文本,如设置filedesc为“请选择rar doc pdf文件”,打开文件选择框效果如下图:
fileext : 设置可以选择的文件的类型,格式如:'*.doc;*.pdf;*.rar' 。
sizelimit : 上传文件的大小限制 。
simuploadlimit : 允许同时上传的个数 默认值:1 。
buttontext : 浏览按钮的文本,默认值:browse 。
buttonimg : 浏览按钮的图片的路径 。
hidebutton : 设置为true则隐藏浏览按钮的图片 。
rollover : 值为true和false,设置为true时当鼠标移到浏览按钮上时有反转效果。
width : 设置浏览按钮的宽度 ,默认值:110。
height : 设置浏览按钮的高度 ,默认值:30。
wmode : 设置该项为transparent 可以使浏览按钮的flash背景文件透明,并且flash文件会被置为页面的最高层。 默认值:opaque 。
cancelimg :选择文件到文件队列中后的每一个文件上的关闭按钮图标

上面介绍的key值的value都为字符串或是布尔类型,比较简单,接下来要介绍的key值的value为一个函数,可以在选择文件、出错或其他一些操作的时候返回一些信息给用户。

oninit : 做一些初始化的工作。

onselect :选择文件时触发,该函数有三个参数

event:事件对象。
queueid:文件的唯一标识,由6为随机字符组成。
fileobj:选择的文件对象,有name、size、creationdate、modificationdate、type 5个属性。
onselectonce :在单文件或多文件上传时,选择文件时触发。该函数有两个参数event,data,data对象有以下几个属性:

filecount:选择文件的总数。
filesselected:同时选择文件的个数,如果一次选择了3个文件该属性值为3。
filesreplaced:如果文件队列中已经存在a和b两个文件,再次选择文件时又选择了a和b,该属性值为2。
allbytestotal:所有选择的文件的总大小。
oncancel : 当点击文件队列中文件的关闭按钮或点击取消上传时触发。该函数有event、queueid、fileobj、data四个参数,前三个参数同onselect 中的三个参数,data对象有两个属性filecount和allbytestotal。

filecount:取消一个文件后,文件队列中剩余文件的个数。
allbytestotal:取消一个文件后,文件队列中剩余文件的大小。
onclearqueue :当调用函数fileuploadclearqueue时触发。有event和data两个参数,同oncancel 中的两个对应参数。

onqueuefull :当设置了queuesizelimit并且选择的文件个数超出了queuesizelimit的值时触发。该函数有两个参数event和queuesizelimit。

onerror :当上传过程中发生错误时触发。该函数有event、queueid、fileobj、errorobj四个参数,其中前三个参数同上,errorobj对象有type和info两个属性。

type:错误的类型,有三种‘http’, ‘io’, or ‘security’
info:错误的描述
onopen :点击上传时触发,如果auto设置为true则是选择文件时触发,如果有多个文件上传则遍历整个文件队列。该函数有event、queueid、fileobj三个参数,参数的解释同上。

onprogress :点击上传时触发,如果auto设置为true则是选择文件时触发,如果有多个文件上传则遍历整个文件队列,在onopen之后触发。该函数有 event、queueid、fileobj、data四个参数,前三个参数的解释同上。data对象有四个属性percentage、 bytesloaded、allbytesloaded、speed:

percentage:当前完成的百分比
bytesloaded:当前上传的大小
allbytesloaded:文件队列中已经上传完的大小
speed:上传速率 kb/s
oncomplete:文件上传完成后触发。该函数有四个参数event、queueid、fileobj、response、data五个参数,前三个参数同上。response为后台处理程序返回的值,在上面的例子中为1或0,data有两个属性filecount和speed

filecount:剩余没有上传完成的文件的个数。
speed:文件上传的平均速率 kb/s
onallcomplete:文件队列中所有的文件上传完成后触发。该函数有event和data两个参数,data有四个属性,分别为:

filesuploaded :上传的所有文件个数。
errors :出现错误的个数。
allbytesloaded :所有上传文件的总大小。
speed :平均上传速率 kb/s

补充:asp.net教程,.Net开发
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,