【分享】 在silverlight中使用wcf上传文件并实时显示进度

【分享】 在silverlight中使用wcf上传文件并实时显示进度,第1张

概述公司一个项目要用到文件上件, Google后了解到上传一般有三种方式:WebClient、WebService和WCF。 最开始用WebClient.OpenWrite实现了文件上传,但弄不明白怎么才能得到上传进度,只好放弃了。 用WebService还不如直接WCF,参考http://www.cnblogs.com/blackcore/archive/2009/11/21/1607823.htm 公司一个项目要用到文件上件, Google后了解到上传一般有三种方式:WebClIEnt、WebService和WCF。

最开始用WebClIEnt.OpenWrite实现了文件上传,但弄不明白怎么才能得到上传进度,只好放弃了。

用WebService还不如直接WCF,参考http://www.cnblogs.com/blackcore/archive/2009/11/21/1607823.HTML后,自己做了一个,最终的效果图如下:



简单实现步骤如下:

一、在sl.Web项目中添加“启用了 Silverlight 的 WCF 服务”。WCF服务的内容十分简单,只需一个功能:接收字节并储存即可。

        代码如下:

    [ServiceContract(namespace = "")]    [SilverlightFaultBehavior]    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]    public class UploadfileWCFService    {        [OperationContract]        public voID DoWork()        {            // 在此处添加 *** 作实现            return;        }        /// <summary>        /// 开始上传。需要在WCF服务启动文件夹下建立Uploadfiles、TempuploadFolder文件夹。        /// Uploadfiles储存上传文件夹        /// TempuploadFolder为上传临时文件夹        /// </summary>        /// <param name="FullPath">保存路径及文件名</param>        /// <param name="fileContext">文件内容</param>        /// <param name="Overwrite">是否覆盖</param>        [OperationContract]        public voID BeginUpload(string FullPath,byte[] fileContext,bool Overwrite)        {            try            {                if (!FullPath.StartsWith("\"))                {                    FullPath = "\" + FullPath;                }                           string defaultFolder = System.Web.Hosting.HostingEnvironment.MapPath("~/Uploadfiles");                string tempuploadFolder = System.Web.Hosting.HostingEnvironment.MapPath("~/TempuploadFolder");                string SaveFolder = Path.GetDirectoryname(FullPath);                string filename = Path.Getfilename(FullPath);                string BlockString = Path.GetExtension(filename);                string[] block = BlockString.Split('-');                if (block.Length != 2)                {                    throw new Exception("系统不支持此 *** 作");                }                int filesIndex = Convert.ToInt32(block[0].Replace(".",""));                int filesCount = Convert.ToInt32(block[1]);                string tempFolder = tempuploadFolder + "\" + Path.GetfilenameWithoutExtension(FullPath); //上传到临时文件夹                 Directory.CreateDirectory(tempFolder);                if (!Directory.Exists(defaultFolder + "\" + SaveFolder))                {                    Directory.CreateDirectory(defaultFolder + "\" + SaveFolder);                }                fileMode mode = fileMode.Create;                if (!Overwrite)                {                    mode = fileMode.Append;                }                using (fileStream fs = new fileStream(tempFolder + "\" + filename,mode,fileAccess.Write))                {                    fs.Write(fileContext,fileContext.Length);                }                if (filesIndex == filesCount - 1)//是否最后一块文件,如是则合并文件块得到完整文件                {                    string Uploadfile = defaultFolder + "\" + SaveFolder + "\" + Path.GetfilenameWithoutExtension(FullPath);                    string[] files = Directory.Getfiles(tempFolder);                    using (fileStream sfile = new fileStream(Uploadfile,fileMode.Create,fileAccess.Write))                    {                        foreach (string file in files)                        {                            using (fileStream fs = new fileStream(file,fileMode.Open,fileAccess.Read))                            {                                byte[] context = new byte[fs.Length];                                fs.Read(context,context.Length);                                sfile.Write(context,context.Length);                            }                            file.Delete(file);                        }                    }                    Directory.Delete(tempFolder);                }            }            catch (Exception)            {                throw;            }            return;        }    }

二、为让WCF服务支持大文件需对sl.Web项目中的web.config进行配置,增加MaxArrayLength属性的设置:

  <system.serviceModel>    <behaviors>      <serviceBehaviors>        <behavior name="">          <serviceMetadata httpGetEnabled="true" />          <serviceDeBUG includeExceptionDetailinFaults="false" />        </behavior>      </serviceBehaviors>    </behaviors>    <bindings>      <customBinding>        <binding name="autoloanMobileManager.Web.Service.UploadfileWCFService.customBinding0">          <binaryMessageEnCoding>          <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"              maxBytesPerRead="2147483647" />          </binaryMessageEnCoding>          <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />        </binding>      </customBinding>    </bindings>    <services>      <service name="autoloanMobileManager.Web.Service.UploadfileWCFService">        <endpoint address="" binding="customBinding" bindingConfiguration="autoloanMobileManager.Web.Service.UploadfileWCFService.customBinding0"          contract="autoloanMobileManager.Web.Service.UploadfileWCFService" />        <endpoint address="mex" binding="mexhttpBinding" contract="IMetadataExchange" />      </service>    </services>    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"      multipleSiteBindingsEnabled="true" />

三、在sl项目中添加上传类,实现上传方法。

       利用WCF异步调用的特点,将要上传的文件分成N个文件块依次上传,由此获得准确的上传进度。代码如下:

   public class WcfUploadfileService : INotifyPropertyChanged    {        public class fileList : INotifyPropertyChanged        {            private voID NotifyPropertyChanged(string info)            {                if (PropertyChanged != null)                {                    PropertyChanged(this,new PropertyChangedEventArgs(info));                }            }            private int m_BufferSize = 4096;            private fileInfo m_fileList;            private UploadStatusType m_UploadStauts;            private long m_BytesSent;            private long m_BytesSentCount;            private int m_SentPercentage;            private string m_SavePath;            private ObservableCollection<UploadLog> m_LOG = new ObservableCollection<UploadLog>();            public enum UploadStatusType            {                Waitting,Uploading,Completed,Failed,Pause            }            /// <summary>            /// 每次上传的字节数。应在给file赋值前设定。            /// </summary>            public int BufferSize            {                get                {                    return m_BufferSize;                }                set                {                    m_BufferSize = value;                }            }            public class UploadLog            {                public UploadLog(DateTime time,string context,object tag)                {                    LogTime = time;                    LogContext = context;                    Tag = tag;                }                public DateTime LogTime { get; set; }                public string LogContext { get; set; }                public object Tag { get; set; }            }            /// <summary>            /// 上传日志            /// </summary>            public ObservableCollection<UploadLog> LOG            {                get                {                    return m_LOG;                }                set                {                    m_LOG = value;                    NotifyPropertyChanged("LOG");                }            }            private voID AddLog(UploadLog log)            {                LOG.Add(log);            }            /// <summary>            /// 等待传输的字节数据列表。设计this.file时自动赋值,按BufferSize读取至Byte[]等待上传。            /// </summary>            public List<Byte[]> fileContext { get; set; }            /// <summary>            /// 要上传的文件            /// </summary>            public fileInfo file            {                get { return m_fileList; }                set                {                    m_fileList = value;                    Stream sourefile = null;                    UploadStatus = UploadStatusType.Waitting;                    try                    {                        sourefile = value.OpenRead();                    }                    catch (Exception)                    {                        UploadStatus = UploadStatusType.Failed;                        AddLog(new UploadLog(DateTime.Now,"无法读取文件",null));                    }                    long BytesCount = sourefile.Length;                    long BytesRead = 0;                    if (fileContext == null)                    {                        fileContext = new List<byte[]>();                    }                    else                    {                        fileContext.Clear();                    }                    long ReadSize = BufferSize;                    while (BytesRead < BytesCount)                    {                        if (BytesRead + BufferSize > BytesCount) //调整最后一个文件块的大小                        {                            ReadSize = BytesCount - BytesRead;                        }                        byte[] bytes = new byte[ReadSize];                        BytesRead += sourefile.Read(bytes,bytes.Length);                        fileContext.Add(bytes);                    }                    sourefile.Close();                    sourefile.dispose();                    NotifyPropertyChanged("file");                }            }            /// <summary>            /// 保存路径            /// </summary>            public string SavePath            {                get { return m_SavePath; }                set { m_SavePath = value; NotifyPropertyChanged("SavePath"); }            }            /// <summary>            /// 上传状态            /// </summary>            public UploadStatusType UploadStatus            {                get { return m_UploadStauts; }                set { m_UploadStauts = value; NotifyPropertyChanged("UploadStatus"); }            }            /// <summary>            /// 本次上传字节            /// </summary>            public long BytesSent            {                get { return m_BytesSent; }                set { m_BytesSent = value; NotifyPropertyChanged("BytesSent"); }            }            /// <summary>            /// 已上传字节            /// </summary>            public long BytesSentCount            {                get { return m_BytesSentCount; }                set { m_BytesSentCount = value; NotifyPropertyChanged("BytesSentCount"); }            }            /// <summary>            /// 已上传比率            /// </summary>            public int SentPercentage            {                get { return m_SentPercentage; }                set { m_SentPercentage = value; NotifyPropertyChanged("SentPercentage"); }            }            #region INotifyPropertyChanged 成员            public event PropertyChangedEventHandler PropertyChanged;            #endregion        }        UploadfileWCFServiceClIEnt uploadClIEnt = new UploadfileWCFServiceClIEnt();        public WcfUploadfileService()        {            uploadClIEnt.BeginUploadCompleted += new EventHandler<AsyncCompletedEventArgs>(uploadClIEnt_BeginUploadCompleted);        }        voID uploadClIEnt_BeginUploadCompleted(object sender,AsyncCompletedEventArgs e)        {            //通过CurrentfileIndex 、CurrentfileContextIndex控制下一个上传的块            bool beginNew = false; //是开始一个新文件或续传            if (e.Error != null)            {                //如错误,放弃当前文件,传下一文件                files[CurrentfileIndex].UploadStatus = fileList.UploadStatusType.Failed;                files[CurrentfileIndex].LOG.Add(new fileList.UploadLog(DateTime.Now,e.Error.Message,null));                CurrentfileIndex++;                CurrentfileContextIndex = 0;                beginNew = true;            }            else            {                files[CurrentfileIndex].BytesSent = files[CurrentfileIndex].fileContext[CurrentfileContextIndex].Length;                files[CurrentfileIndex].BytesSentCount += files[CurrentfileIndex].BytesSent;                files[CurrentfileIndex].SentPercentage = Convert.ToInt32((double)files[CurrentfileIndex].BytesSentCount / (double)files[CurrentfileIndex].file.Length * 100);                //计算下一个上传的文件号和块号                if (CurrentfileIndex < files.Count)                {                    if (CurrentfileContextIndex < files[CurrentfileIndex].fileContext.Count - 1)                    {                        CurrentfileContextIndex++;                    }                    else                    {                        files[CurrentfileIndex].UploadStatus = fileList.UploadStatusType.Completed;                        CurrentfileIndex++;                        CurrentfileContextIndex = 0;                        beginNew = true;                    }                }            }            if (CurrentfileIndex < files.Count)            {                files[CurrentfileIndex].UploadStatus = fileList.UploadStatusType.Uploading;                uploadClIEnt.BeginUploadAsync(files[CurrentfileIndex].SavePath + "//"                    + files[CurrentfileIndex].file.name + "."                     + CurrentfileContextIndex.ToString().Padleft(9,'0')                    + "-" + files[CurrentfileIndex].fileContext.Count,files[CurrentfileIndex].fileContext[CurrentfileContextIndex],beginNew);            }            else            {                files[CurrentfileIndex - 1].UploadStatus = fileList.UploadStatusType.Completed;            }        }        private ObservableCollection<fileList> m_files = new ObservableCollection<fileList>();        /// <summary>        /// 准备上传的文件列表        /// </summary>        public ObservableCollection<fileList> files        {            get            {                return m_files;            }            set            {                m_files = value;                NotifyPropertyChanged("files");            }        }        /// <summary>        /// 当前上传的文件索引        /// </summary>        private int CurrentfileIndex;        /// <summary>        /// 当前上传的文件块索引        /// </summary>        private int CurrentfileContextIndex;        /// <summary>        /// 开始上传。按BufferSize将文件分块,块命名规则为 filename.blockID-blockcount,服务器接收完最后一块后合并成源文件。        /// </summary>        public voID BeginUpload()        {            if (files.Count > 0)            {                CurrentfileIndex = 0;                CurrentfileContextIndex = 0;                files[CurrentfileIndex].UploadStatus = fileList.UploadStatusType.Uploading;                uploadClIEnt.BeginUploadAsync(files[CurrentfileIndex].SavePath + "//"                    + files[CurrentfileIndex].file.name + "."                    + CurrentfileContextIndex.ToString().Padleft(9,true);            }        }        #region INotifyPropertyChanged 成员        public event PropertyChangedEventHandler PropertyChanged;        private voID NotifyPropertyChanged(string info)        {            if (PropertyChanged != null)            {                PropertyChanged(this,new PropertyChangedEventArgs(info));            }        }        #endregion

四、制作简单的上传控件,代码如下:


<UserControl x:Class="autoloanMobileManager.Controls.UploadfileControl"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:d="http://schemas.microsoft.com/Expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    mc:Ignorable="d">        <GrID>            <GrID.ColumnDeFinitions>                <ColumnDeFinition WIDth="70"/>                <ColumnDeFinition WIDth="*"/>            </GrID.ColumnDeFinitions>        <Progressbar x:name="uploadProgress" Value="{Binding SentPercentage}" Height="20"                      Background="Yellow" WIDth="400" GrID.Column="1"/>        <StackPanel OrIEntation="Horizontal" GrID.Column="1" HorizontalAlignment="Right">            <TextBlock Text="{Binding BytesSentCount}" VerticalAlignment="Center"/>            <TextBlock Text="/" VerticalAlignment="Center"/>            <TextBlock Text="{Binding file.Length}" VerticalAlignment="Center"/>        </StackPanel>        <TextBlock Text="{Binding file.name}" GrID.Column="1" HorizontalAlignment="left"                    VerticalAlignment="Center" Foreground="DarkBlue"                   margin="8,0"/>            <TextBlock Text="{Binding UploadStatus}" GrID.Column="0" VerticalAlignment="Center"/>        </GrID></UserControl>

五、新建一个Page,前台界面如下:

        注意添加第四步中定义的UploadfileControl的引用

<navigation:Page x:Class="autoloanMobileManager.Pages.UploadfilePage"            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"            xmlns:d="http://schemas.microsoft.com/Expression/blend/2008"           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"                 xmlns:control="clr-namespace:autoloanMobileManager.Controls"           mc:Ignorable="d"           xmlns:navigation="clr-namespace:System.windows.Controls;assembly=System.windows.Controls.Navigation"           d:DesignWIDth="640" d:DesignHeight="480"           title="UploadfilePage Page">    <StackPanel>        <ListBox margin="10" x:name="List_uploadList">            <ListBox.ItemTemplate>                <DataTemplate>                    <control:UploadfileControl/>                </DataTemplate>            </ListBox.ItemTemplate>        </ListBox>        <button Content="选择文件" Click="button_Click" WIDth="80" HorizontalAlignment="left" margin="5"/>    </StackPanel></navigation:Page>

后台代码:

public partial class UploadfilePage : Page    {        WcfUploadfileService upload = new WcfUploadfileService();        public UploadfilePage()        {            InitializeComponent();            List_uploadList.ItemsSource = upload.files;        }        // 当用户导航到此页面时执行。        protected overrIDe voID OnNavigatedTo(NavigationEventArgs e)        {        }        private voID button_Click(object sender,RoutedEventArgs e)        {            OpenfileDialog file = new OpenfileDialog();            file.Multiselect = true;            bool? result = file.ShowDialog();            if (result.HasValue)            {                if (result.Value)                {                    upload.files.Clear();                    foreach (System.IO.fileInfo f in file.files)                    {                        WcfUploadfileService.fileList fileList = new WcfUploadfileService.fileList();                        fileList.SavePath = "20120222";                        fileList.BufferSize = 1024 * 32;                        fileList.file = f;                        upload.files.Add(fileList);                    }                    upload.BeginUpload();                }            }        }    }



HOHO运行一下看效果怎么样吧!


项目源码 我接触siverlight和wcf不久,望大牛指教啊。

总结

以上是内存溢出为你收集整理的【分享】 在silverlight中使用wcf上传文件并实时显示进度全部内容,希望文章能够帮你解决【分享】 在silverlight中使用wcf上传文件并实时显示进度所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1069912.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存