Dev.Hong
将欲取之 必先予之……
随笔- 53  文章- 0  评论- 220 
博客园  首页  新随笔  联系  管理  订阅 订阅
共享一个在SilverLight下的文件上传组件(支持大文件,断点续传)

 

请关注此组件的朋友看这里

 

先看一下运行效果图(本人的UI水平很菜,无法用SilverLight做出很炫的界面来)

初始状态
1.jpg
选择上传文件后
2.jpg
中断文件传输
3.JPG
再次上传文件,是续传而不是从新上传
4.jpg
上传完毕
5.jpg

先看看服务器端:
项目 FileUpLoad.Service 为上传组件的服务器端实现,
IUpLoadService为文件上传WCF服务契约

    /// <summary>
    
/// 文件上传WCF服务契约
    
/// </summary>
    [System.ServiceModel.ServiceContract]
    
public interface IUpLoadService
    {
        
/// <summary>
        
/// 开始一个文件的上传操作
        
/// 在每次文件上传之前会检查是否已存在此文件片断, 
        
/// 如果存在并且当参数keepOn==true时, 则返回该片断的相关信息, 否则删除此文件片断
        
/// </summary>
        
/// <param name="fileName">表示上传之后保存的文件名,不允许为NULL</param>
        
/// <param name="fileLength">此文件的总大小</param>
        
/// <param name="guid">用于标识此文件的唯一ID</param>
        
/// <param name="keepOn">标识是否需要续传</param>
        
/// <returns></returns>
        [System.ServiceModel.OperationContract]
        UpLoadReadyInfo BeginUpLoad(
string fileName, long fileLength, string guid, bool keepOn);

        
/// <summary>
        
/// 上传文件内容
        
/// </summary>
        
/// <param name="bytes">文件内容</param>
        
/// <param name="guid">用于标识此文件传输的唯一ID</param>
        
/// <returns>
        
/// 如果在执行此方法时服务器端发生异常时,则返回的CallbackResult中Error表示对此异常的描述
        
/// 如果返回的CallBackResult==null则表示没有异常
        
/// </returns>
        [System.ServiceModel.OperationContract]
        CallBackResult UpLoad(System.Byte[] bytes, 
string guid);

        
/// <summary>
        
/// 用于客户端手工终止文件的上传
        
/// </summary>
        
/// <param name="guid">用于标识此文件传输的唯一ID</param>
        
/// <param name="keepOn">指示是否需要保留此文件片断,以便下次进行续传</param>
        [System.ServiceModel.OperationContract]
        
void Abort(string guid, bool keepOn);
    }

UpLoadFileManager对象是用来管理文件上传的相关信息,它的相关事件如下:
        /// <summary>
        
/// 开始一个新的文件上传操作事件
        
/// </summary>
        public event System.EventHandler<UpLoadBeginEventArgs> UpLoadBegin;
        
/// <summary>
        
/// 正在上传时引发的事件
        
/// </summary>
        public event System.EventHandler<UpLoadingEventArgs> UpLoading;
        
/// <summary>
        
/// 文件上传完毕事件
        
/// </summary>
        public event System.EventHandler<FileUpLoadEventArgs> UpLoadCompleted;
        
/// <summary>
        
/// 中止文件上传事件
        
/// </summary>
        public event System.EventHandler<FileUpLoadEventArgs> UpLoadAborted;

订阅以上事件即可在服务器端掌握文件上传的一切信息。

如何托管FileUpLoad组件的服务器端呢?
新建一Asp.net Application,并添加WCF Service, (如MyUpLoadService.svc) 删除系统自动生成的契约文件,让MyUpLoadService类继承自Jon.FileUpLoad.Service.UpLoadService,并重写以下方法
        /// <summary>
        
/// 重写目录存放路径
        
/// </summary>
        protected override string UpLoadFolder
        {
            
get
            {
                
return System.Threading.Thread.GetDomain().BaseDirectory;
            }
        }

        
/// <summary>
        
/// 重写基类方法,,用于订阅 UpLoadFileManager 相关事件
        
/// </summary>
        
/// <param name="manager"></param>
        protected override void OnUpLoadFileManagerRegister(Jon.FileUpLoad.Service.UpLoadFileManager manager)
        {
            manager.UpLoadBegin 
+= delegate(object sender, Jon.FileUpLoad.Service.UpLoadBeginEventArgs e)
            {
            };
            manager.UpLoadCompleted 
+= delegate(object sender, Jon.FileUpLoad.Service.FileUpLoadEventArgs e)
            {
            };
            manager.UpLoadAborted 
+= delegate(object sender, Jon.FileUpLoad.Service.FileUpLoadEventArgs e)
            {
            };
            manager.UpLoading 
+= delegate(object sender, Jon.FileUpLoad.Service.UpLoadingEventArgs e)
            {
            };
            
//
        }
附上配置文件
  <system.serviceModel>
    
<behaviors>
      
<serviceBehaviors>
        
<behavior name="FileUpLoad.Service.Host.UpLoadServiceBehavior">
          
<serviceMetadata httpGetEnabled="true" />
          
<serviceDebug includeExceptionDetailInFaults="false" />
        
</behavior>
      
</serviceBehaviors>
    
</behaviors>
    
<services>
      
<service behaviorConfiguration="FileUpLoad.Service.Host.UpLoadServiceBehavior" name="FileUpLoad.Service.Host.UpLoadService">
        
<endpoint address="" bindingConfiguration="LargeBuffer" binding="basicHttpBinding" contract="Jon.FileUpLoad.Service.IUpLoadService" />
      
</service>
    
</services>
    
<bindings>
      
<basicHttpBinding>
        
<binding name="LargeBuffer" maxBufferSize="4096000" maxReceivedMessageSize="4096000">
          
<readerQuotas maxDepth="4096000" maxStringContentLength="4096000" maxArrayLength="4096000" maxBytesPerRead="4096000" maxNameTableCharCount="4096000"/>
        
</binding>
      
</basicHttpBinding>
    
</bindings>
  
</system.serviceModel>

(注意,如果你的客户端和服务端不是在同一域下,也就是跨域调用的话,则别忘了在服务端新建策略文件http://www.cnblogs.com/T-MAC/archive/2008/08/07/1262619.html,并且确保上传目录具有写的权限)

至此,服务端方面的就结束了,下面说说客户端怎么使用。

新建一SilverLight Application,添加对 FileUpLoad 项目的引用。

初始化Jon.FileUpLoad.FileUpLoad对象
        protected Jon.FileUpLoad.FileUpLoad GetFileUpLoad()
        {
            
if (this.objFileUpload == null)
            {
                objFileUpload 
= new Jon.FileUpLoad.FileUpLoad("http://localhost/FileUpLoadService/UpLoadService.svc");
                objFileUpload.UpLoadBegin 
+= new EventHandler<Jon.FileUpLoad.UpLoadBeginEventArgs>(objFileUpload_UpLoadBegin);
                objFileUpload.UpLoading 
+= new EventHandler<Jon.FileUpLoad.UpLoadingEventArgs>(objFileUpload_UpLoading);
                objFileUpload.UpLoadCompleted 
+= new EventHandler<Jon.FileUpLoad.FileUpLoadEventArgs>(objFileUpload_UpLoadCompleted);
                objFileUpload.UpLoadAborted 
+= new EventHandler<Jon.FileUpLoad.FileUpLoadEventArgs>(objFileUpload_UpLoadAborted);
            }
            
return objFileUpload;
        }

上传文件,
        void btSelectFile_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog fd 
= new OpenFileDialog();
            
if (fd.ShowDialog() == true)
            {
                
this.lblFileName.Text = fd.SelectedFile.Name;
                
this.objCurrentUploadGuid = this.GetFileUpLoad().UpLoad(fd.SelectedFile);
            }
        }
具体的使用代码请参照 FileUpLoad.Client 项目中的Page类里面代码。

源码请从此处下载
posted on 2008-08-14 10:41 Dev.Hong 阅读(2213) 评论(13) 编辑 收藏
刷新评论刷新页面返回顶部
程序员问答社区,解决您的IT难题
博客园首页博问新闻闪存程序员招聘知识库
Copyright ©2012 Dev.Hong