Silverlight之文件上传组件

本文介绍如何使用Silverlight组件"CmjUpload"实现大文件、多文件上传,无需部署WCF或WebService,支持选择、拖拽上传,具备取消、暂停、继续功能。通过WebRequest异步发送文件,实现文件分块上传并显示进度。
摘要由CSDN通过智能技术生成

摘要:

文件上传是日常开过程中最常用的功能之一,目前实现文件上传的方式多种多样。这其中较为复杂的情况就是关于大文件、多文件上传的问题,目前解决大文件、多文件上传一般借助于js或者flash组件,今天就同大家一起看一下如何使用silverlight实现这个功能,而且功能和用户体验相对会更好一些。

主要内容:

一、组件特点

二、实现原理

三、编码实现

一、组件特点

对于今天要说的组件姑且叫做"CmjUpload"吧,方便称呼。目前有很多上传组件来辅助完成日常开发,"CmjUpload"有什么特点呢:

  1. 解决大文件、多文件上传问题
  2. 基于asp.net上传,不需要部署WCF、WebService操作方便
  3. 接口丰富、灵活性强,配置使用方便。
  4. 支持选择、拖拽两种文件添加方式上传,用户体验好。
  5. 支持取消、暂停、继续操作满足续传要求。

OK,就说那么多吧,主要是让大家有兴趣看下去,其实之所以有今天的话题主要还是为了学习以及满足实际开发需求。

二、实现原理

在Silverlight中要实现上传有很多方式,例如说使用WCF或者WebService,但是考虑到实际情况,这里没有选择以上两种方式,而是选择了WebRequest方式。原因比较简单,部署十分方便,不需要为了上传组件而进行额外的配置。Silverlight中使用WebRequest同其他.Net开发中的使用方式是类似的,不同的是Silverlight中很多操作都是异步的,当然WebRequest也不例外。此外,在这里需要对一个文件分块发送,一方面可以解决大文件上传问题,另一方面可以实时显示文件上传进度。下面一个简单的交互过程:

 analysisDesgin

当然要完成整个组件远不止上面说的这些,UI的设计,组件的本地化,用户接口的设计等都是必须思考的问题。下面是组件界面原型:

mockup

界面分为两个区域:文件显示区域和操作区域,当然这里的文件区域本身也是可以操作的,例如如果你不想点击按钮选择文件的话,可以选择直接拖拽一个或多个文件到文件区域。还可以对已添加的文件进行删除操作,对正在上传的文件进行暂停和续传操作。此外文件区域的设计主要提供文件信息显示,例如缩略图、上传进度、文件名称、文件大小等信息。操作区域一方面提供文件整体信息的显示(例如文件总数、已上传数等),另一方面提供了文件浏览、上传、清空操作。

下面是类的设计:

classDesgin

在上图中我们可以看出有三个包:Core、Config、Util。

Core是核心包,里面主要包括文件队列管理(FileQueue)、文件上传控制(FileUpload)、文件界面区域(FileArea)、文件大小单位转换(FileSize)、缩略图控制(FileIcon)。

Config是配置和接口包,主要包括组件设计级别常量(注意不是用户级别也不是开发级别,开发级别配置在接口中进行)(UploadConstant)、客户端开发接口(ExposeInterface)、本地化实现(Localization)、接口注册(ClientInteraction)。

Util包主要包括一些常用辅助类,主要包括xml操作(XmlHelper)、服务器端文件保存辅助类(CmjUpload)。

三、编码实现

有了上面的分析相信下面的实现就相当容易理解了,首先看一下文件上传类FileUpload:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Text;
using System.IO;
using System.Windows.Threading;
using CmjUpload.Util;
using CmjUpload.Config;
 
namespace CmjUpload
{
    public class FileUpload
    {
        //开始上传
        public delegate void StartUploadHanler(object sender,EventArgs e);
        public event StartUploadHanler StartUpload;
        public void OnStartUpload(object sender, EventArgs e)
        {
            if (StartUpload != null)
            {
                StartUpload(sender, e);
            }
        }
 
        // 上传
        public delegate void UploadingHanler(object sender, ProgressArgs e);
        public event UploadingHanler Uploading;
        public void OnUploading(object sender, ProgressArgs e)
        {
            if (Uploading != null)
            {
                Uploading(sender,e);
            }
        }
 
        //上传结束
        public delegate void UploadCompletedHanler(object sender, EventArgs e);
        public event UploadCompletedHanler UploadCompleted;
        public void OnUploadCompleted(object sender, EventArgs e)
        {
            if (UploadCompleted != null)
            {
                UploadCompleted(sender, e);
            }
        }
 
 
        private string _requestUrl = "";
        private string _fileName = "";
        private long _fileLength = 0;
        private long _blockLength = 4096;//单次上传文件大小
        private long _postedLength = 0;//已传输文件大小
        private long _nextLength = 0;//下次传输的文件大小
        private bool _firstUpload = true;
        private BinaryReader _fileReader = null;
 
        private UploadStatus _uploadStatus = UploadStatus.Start;
 
        public FileInfo File
        {
            get;
            set;
        }
 
        //public long PostedLength
        //{
        //    get
        //    {
        //        return _postedLength;
        //    }
        //    set
        //    {
        //        _postedLength = value;
        //    }
        //}
 
        public UploadStatus Status
        {
            get
            {
                return _uploadStatus;
            }
            set
            {
                _uploadStatus = value;
            }
        }
 
        public void Upload(FileInfo file)
        {
            this.File = file;
            //XmlHelper xmlHelper = new XmlHelper("Config/CmjUploadConfig.xml");
            //_requestUrl=xmlHelper.GetAttibuteValue("Upload", "RequestUrl");
            _requestUrl = ExposeInterface.Instance().RequestUrl;
            this._fileName = this.File.Name;
            this._fileLength = this.File.Length;
            this._blockLength = FileSize.GetLockSize(this._fileLength);
            //this._postedLength = 0;
            _fileReader = new BinaryReader(file.OpenRead());
            //_uploadStatus = UploadStatus.Start;
            if (_fileLength < _blockLength)
            {
                _nextLength = _fileLength;
            }
            else
            {
                _nextLength = _blockLength;
            }
            OnStartUpload(this, new EventArgs());
 
            UploadInBlock();
        }
 
        public void UploadInBlock()//上传一块数据
        {
            UriBuilder uriBuilder = new UriBuilder(new Uri(_requestUrl, UriKind.Absolute));
            uriBuilder.Query = string.Format("fileName={0}&status="+_uploadStatus,this._fileName);
            WebRequest request = WebReq
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值