DiscuzNT使用Silverlight进行多文件上传(上)

   在去年我曾写过一篇文章:“ 推荐一个Silverlight多文件(大文件)上传的开源项目”。之后有不少朋友询问这个项目示例在开发和配置上的一些问题。当时因为时间有限没有做过多的说明,导致有些问题在大家下载完源码之后运行时才出现。今天就以这个项目为原型,简要介绍一下在DiscuzNT上是如果在该项目基本上,通过完善权限管理,文件大小控制,添加缩略图效果等功能来大体阐述一下如果开发一个真正的silverlight应用,而不是一个简单的DEMO.
      当然本文中所列出的源码是通过reflector获取并添加相应注释的。最终的源码还是要以开放出来的为准,呵呵:)

      好了,开始今天的正文吧!
    
      首先,看一下这个插件在DiscuzNT中的实际运行效果:    
    
    
    
    
    

    
 
     
     
       当我们在网页中点击“批量上传”按钮时,会运行如下JS脚本(文件位于Discuz.Web\templates\default_postattachments.htm):
function  LoadSilverlight(pluginID, max) {
     
     Silverlight.createObject(
         
" silverlight/UploadFile/ClientBin/MultiFileUpload.xap "
         $(
" silverlightControlHost " ),         
         pluginID,                         
         {     
             width: 
' 500 ' ,
             height: 
' 440 ' ,
             inplaceInstallPrompt: 
' true ' ,
             isWindowless: 
' true ' ,
             background: 
' transparent ' ,
             version: 
' 2.0 ' ,
             autoUpgrade: 
' true '
         },
         {
             onLoad: onLoad, 
             onError: onSilverlightError
         },
         
<% csharp %>
         string authToken 
=  Discuz.Common.DES.Encode(oluserinfo.Olid.ToString()  +   " , "   +  
         oluserinfo.Username.ToString(), oluserinfo.Password.Substring(
0 10 )).Replace( " + " " [ " );
         
<% / csharp%> 
          " forumid={forumid},authToken={authToken},max= "   +  max,
         
"" );
}
 
        其会将当前版块id(forumid),认证Token,最大上传数等信息以参数形式传给SL插件,而我专门定义了一个方法用于获取相应的参数并绑定到sl变量,如下(Page.xaml.cs): 
///   <summary>
 
///  加载配置参数
 
///   </summary>
 
///   <param name="initParams"></param>
  private   void  LoadConfiguration(IDictionary < string string >  initParams)
 {
     
string  tryTest  =   string .Empty;

     
// 加载定制配置信息串
     _customParams  =  initParams[ " forumid " ];

     
if  (initParams.ContainsKey( " MaxUploads " &&   ! string .IsNullOrEmpty(initParams[ " MaxUploads " ]))
         
int .TryParse(initParams[ " MaxUploads " ],  out  _maxUpload);            

     
if  (initParams.ContainsKey( " MaxFileSizeKB " &&   ! string .IsNullOrEmpty(initParams[ " MaxFileSizeKB " ]))
     {
         
if  ( int .TryParse(initParams[ " MaxFileSizeKB " ],  out  _maxFileSize))
             _maxFileSize 
=  _maxFileSize  *   1024 ;
     }

     
if  (initParams.ContainsKey( " FileFilter " &&   ! string .IsNullOrEmpty(initParams[ " FileFilter " ]))
         _fileFilter 
=  initParams[ " FileFilter " ];          

     
if  (initParams.ContainsKey( " forumid " &&   ! string .IsNullOrEmpty(initParams[ " forumid " ]))
         _forumid 
=  Utils.StrToInt(initParams[ " forumid " ],  0 );

     
if  (initParams.ContainsKey( " max " &&   ! string .IsNullOrEmpty(initParams[ " max " ]))
         _maxAttachments 
=  Utils.StrToInt(initParams[ " max " ],  0 );

     CredentialInfo _creInfo
=  Utils.GetCredentialInfo();
     
if  (_creInfo.UserID  <=   0 )
     {
         ShowMessageBox(
" 您未登陆系统 " );
         SetUploadButton(
false );
         
return ;
     }
     
else
     {
         MixObjectsSoapClient _client 
=  Utils.CreateServiceClient();
         _client.GetAttachmentUploadSetCompleted 
+=   new  EventHandler < GetAttachmentUploadSetCompletedEventArgs >
                                (_client_GetAttachmentUploadSetCompleted);
         _client.GetAttachmentUploadSetAsync(_creInfo, _forumid);
     }
 }

        
        
        大家看到在该方法在获取相应初始化参数(initParams)后,会调用Utils.GetCredentialInfo()来获取 用户登陆信息:
///   <summary>
///  获取认证信息
///   </summary>
///   <returns></returns>
public   static  CredentialInfo GetCredentialInfo()
{
        CredentialInfo _creinfo 
=   new  CredentialInfo();
        _creinfo.UserID 
=  Utils.StrToInt(Utils.GetCookie( " userid " ),  0 );
        _creinfo.Password 
=  Utils.GetCookie( " password " );

        
if  (App.GetInitParmas.ContainsKey( " authToken " &&   ! string .IsNullOrEmpty(App.GetInitParmas[ " authToken " ]))
            _creinfo.AuthToken 
=  App.GetInitParmas[ " authToken " ];

        
if  (App.GetInitParmas.ContainsKey( " forumid " &&   ! string .IsNullOrEmpty(App.GetInitParmas[ " forumid " ]))
            _creinfo.ForumID 
=  StrToInt(App.GetInitParmas[ " forumid " ],  0 );

        
return  _creinfo;
}

        
    其中最主要的就是获取相应的UserID,而这个操作是交给GetCookie来完成的:
      

public   static   string  GetCookie(String key)
{
     
if  ( string .IsNullOrEmpty(HtmlPage.Document.Cookies))
         
return   null ;

     
// 找到想应的cookie键值
      string  result  =  (from c  in
                          (from cookie 
in  HtmlPage.Document.Cookies.Split( ' ; ' )
                           
where  cookie.Contains(key  +   " = " )
                           select cookie.Split(
' & ' )).FirstOrDefault()
                      
where  c.Contains(key  +   " = " )
                      select c).FirstOrDefault().ToString();

     
if ( string .IsNullOrEmpty(result))
         
return   null ;

     
return  result.Substring(result.IndexOf(key  +   " = " +  key.Length  +   1 );
}

 
      其主要是通过用户本地的Cookie,来获取相应的用户信息。
    
      如果用户的Cookie有效(已登陆过),则直接获取该用户所在用户组及其它相关联的权限信息, 如果无效,则提示用户登陆,同时将SL中的几个上传按钮“置灰”,以免未登陆的用户上传附件。
   
      下面就是其向服务器请求谁信息的代码:
 MixObjectsSoapClient _client  =  Utils.CreateServiceClient();
 _client.GetAttachmentUploadSetCompleted 
+=   new  EventHandler < GetAttachmentUploadSetCompletedEventArgs >
                               (_client_GetAttachmentUploadSetCompleted);
 _client.GetAttachmentUploadSetAsync(_creInfo, _forumid);
     
      上面客户端请求下面的服务端代码:     
///   <summary>
///  通过指定用户认证信息来获得该用户的上传设置信息
///   </summary>
///   <param name="creinfo"> 用户认证信息 </param>
///   <returns></returns>
[WebMethod]
public  UploadSetInfo GetAttachmentUploadSet(CredentialInfo creinfo)
{
    
if  (AuthenticateUser(creinfo))
    {
        UserInfo userinfo 
=  Discuz.Forum.Users.GetUserInfo(creinfo.UserID);
        
if  (userinfo  ==   null )
            
return   new  UploadSetInfo( "" "" 0 0 false 0 " 当前用户信息无效,请尝试刷新 " );

        UserGroupInfo usergroupinfo 
=  Discuz.Forum.UserGroups.GetUserGroupInfo(userinfo.Groupid);
        
if  (usergroupinfo  ==   null )
            
return   new  UploadSetInfo( "" "" 0 0 false 0 " 当前用户所属用户组信息无效 " );


        ForumInfo forum 
=  Discuz.Forum.Forums.GetForumInfo(creinfo.ForumID);
        
if  (forum  ==   null )
            
return   new  UploadSetInfo( null null 0 0 false 0 " 当前版块信息无效,请尝试刷新 " );

        
// 得到用户可以上传的文件类型
        StringBuilder sbAttachmentTypeSelect  =   new  StringBuilder();
        
if  ( ! usergroupinfo.Attachextensions.Trim().Equals( "" ))
        {
            sbAttachmentTypeSelect.Append(
" [id] in ( " );
            sbAttachmentTypeSelect.Append(usergroupinfo.Attachextensions);
            sbAttachmentTypeSelect.Append(
" ) " );
        }

        
if  ( ! forum.Attachextensions.Equals( "" ))
        {
            
if  (sbAttachmentTypeSelect.Length  >   0 )
                sbAttachmentTypeSelect.Append(
"  AND  " );

            sbAttachmentTypeSelect.Append(
" [id] in ( " );
            sbAttachmentTypeSelect.Append(forum.Attachextensions);
            sbAttachmentTypeSelect.Append(
" ) " );
        }
        
string  attachextensions  =  Discuz.Forum.Attachments.GetAttachmentTypeArray(sbAttachmentTypeSelect.ToString());
        
string  attachextensionsnosize  =  Discuz.Forum.Attachments.GetAttachmentTypeString(sbAttachmentTypeSelect.ToString());

        
// 得到今天允许用户上传的附件总大小(字节)
         int  MaxTodaySize  =   0 ;
        
if  (creinfo.UserID  >   0 )
            MaxTodaySize 
=  Discuz.Forum.Attachments.GetUploadFileSizeByuserid(creinfo.UserID);

        
int  attachsize  =  usergroupinfo.Maxsizeperday  -  MaxTodaySize; // 今天可上传大小

        
bool  canpostattach  =   false // 是否允许上传附件
        
// 是否有上传附件的权限
         if  (Discuz.Forum.Forums.AllowPostAttachByUserID(forum.Permuserlist, creinfo.UserID))
            canpostattach 
=   true ;
        
else
        {
            
if  (forum.Postattachperm  ==   "" )
            {
                
if  (usergroupinfo.Allowpostattach  ==   1 )
                    canpostattach 
=   true ;
            }
            
else
            {
                
if  (Discuz.Forum.Forums.AllowPostAttach(forum.Postattachperm, usergroupinfo.Groupid))
                    canpostattach 
=   true ;
            }
        }
        
return   new  UploadSetInfo(attachextensions, attachextensionsnosize, MaxTodaySize, attachsize, 
                            canpostattach , usergroupinfo.Maxattachsize, 
"" );
    }

    
return   new  UploadSetInfo( "" "" 0 0 false 0 " 当前用户信息无效,请尝试刷新 " );
}

 
     该方法的首先会访问AuthenticateUser方法来进行用户身份验证:
    
/// <summary>
/// WEB权限认证
///   </summary>
///   <param name="creinfo"> 认证信息 </param>
///   <returns> 是否通过验正 </returns>
private   bool  AuthenticateUser(CredentialInfo creinfo)
{
    
if  (creinfo.ForumID  >   0 )
    {
        
int  olid  =  Discuz.Forum.OnlineUsers.GetOlidByUid(creinfo.UserID);
        
if  (olid  >   0 )
        {
            OnlineUserInfo oluserinfo 
=  Discuz.Forum.OnlineUsers.GetOnlineUser(olid);
            
if  (oluserinfo.Userid  ==  creinfo.UserID  &&  
                Utils.UrlEncode(Discuz.Forum.ForumUtils.SetCookiePassword(oluserinfo.Password, 
                 GeneralConfigs.GetConfig().Passwordkey)) 
==  creinfo.Password  && // 检测用户id和口令
                creinfo.AuthToken  ==  DES.Encode( string .Format( " {0},{1} " , oluserinfo.Olid.ToString(), 
                  oluserinfo.Username.ToString()), oluserinfo.Password.Substring(
0 10 )).Replace( " + " " [ " )) // 检查认证信息
            {
                
return   true ;
            }
        }
    }
    
return   false ;
}
    
       其会对用户的UserId与用户在线表中的数据进行比对,以确保其信息有效,同时还会检查AuthToken来避免用户通过伪造用户信息来进行信息提交。当上面方法返回TRUE时,则将对用户所在版块的权限信息进行获取,并返回一个名为UploadSetInfo类实例,其包括:
    1.用户可以上传的文件类型
    2.用户可以上传的文件类型(不带上传数据大小)
    3.得到今天允许用户上传的附件总大小(字节)
    4.是否允许上传附件
    5.单个附件大小
    6.最大允许上传的附件数
    7.错误信息
     
#region  上传设置信息类
    
///   <summary>
    
///  上传设置信息类
    
///   </summary>
     public   class  UploadSetInfo
    {
        
public  UploadSetInfo()
        { }

        
public  UploadSetInfo( string  attachExtensions,  string  attachExtensionsNoSize,  int  maxTodaySize, 
                  
int  attachSize,  bool  canPostAttach,  int  maxAttachSize,  string  errMessage)
        {
            m_attachExtensions 
=  attachExtensions;
            m_attachExtensionsNoSize 
=  attachExtensionsNoSize;
            m_maxTodaySize 
=  maxTodaySize;
            m_attachSize 
=  attachSize;
            m_canPostAttach 
=  canPostAttach;
            m_maxAttachSize 
=  maxAttachSize;
            m_errMessage 
=  errMessage;
            m_maxAttachments 
=  GeneralConfigs.GetConfig().Maxattachments;
        }

        
private   string  m_attachExtensions;
        
///   <summary>
        
///  用户可以上传的文件类型
        
///   </summary>
         public   string  AttachExtensions
        {
            
get  {  return  m_attachExtensions; }
            
set  { m_attachExtensions  =  value; }
        }

        
private   string  m_attachExtensionsNoSize;
        
///   <summary>
        
///  用户可以上传的文件类型(不带上传数据大小)
        
///   </summary>
         public   string  AttachExtensionsNoSize
        {
            
get  {  return  m_attachExtensionsNoSize; }
            
set  { m_attachExtensionsNoSize  =  value; }
        }

        
private   int  m_maxTodaySize;
        
///   <summary>
        
///  得到今天允许用户上传的附件总大小(字节)
        
///   </summary>
         public   int  MaxTodaySize
        {
            
get  {  return  m_maxTodaySize; }
            
set  { m_maxTodaySize  =  value; }
        }

        
private   int  m_attachSize;
        
///   <summary>
        
///  今天可上传的大小
        
///   </summary>
         public   int  AttachSize
        {
            
get  {  return  m_attachSize; }
            
set  { m_attachSize  =  value; }
        }

        
private   bool  m_canPostAttach;
        
///   <summary>
        
///  是否允许上传附件
        
///   </summary>
         public   bool  CanPostAttach
        {
            
get  {  return  m_canPostAttach; }
            
set  { m_canPostAttach  =  value; }
        }

        
private   int  m_maxAttachSize;
        
///   <summary>
        
///  单个附件大小
        
///   </summary>
         public   int  MaxAttachSize
        {
            
get  {  return  m_maxAttachSize; }
            
set  { m_maxAttachSize  =  value; }
        }

        
private   string  m_errMessage;
        
///   <summary>
        
///  错误信息
        
///   </summary>
         public   string  ErrMessage
        {
            
get  {  return  m_errMessage; }
            
set  { m_errMessage  =  value; }
        }

        
private   int  m_maxAttachments;
        
///   <summary>
        
///  最大允许上传的附件数
        
///   </summary>
         public   int  Maxattachments
        {
            
get  {  return  m_maxAttachments; }
            
set  { m_maxAttachments  =  value; }
        }
    }
    
#endregion


        如果一切顺利,客户端会获取相应的UploadSetInfo实例信息来进行SL插件的信息绑定,也就是之前第二张图中所说的信息内容(红框部分)。


本文转自 daizhenjun 51CTO博客,原文链接:http://blog.51cto.com/daizhj/147172,如需转载请自行联系原作者
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值