Silverlight通过WebService上传大文件(可拓展为支持断点续传)
转自:http://blog.csdn.net/luminji/article/details/4987539
GOOGLE一遍,没发现网上有现成代码,没办法,只有对一些零散代码进行改造,得到了本文要达到的效果:
1:服务器端采用webservice;
2:SilverLight端可同时选择多个文件;
3:显示每个文件的上传进度,并可拓展为断点续传;
本文源码下载地址:http://download.csdn.net/source/1893588
首先,生成一个SILVERLIGHT应用程序,选择创建WEB。在WEB中新建WEBSERVICE:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services; using System.IO; using System.Xml.Serialization; namespace SilverlightApplication6.Web { /// <summary> /// WebService1 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 // [System.Web.Script.Services.ScriptService] public class WebService1 : System.Web.Services.WebService { [WebMethod] public string HelloWorld() { return "Hello World"; } /// <summary> /// 大文件上传.<br></br> /// 2009-05-12 YJ 定义函数.<br></br> /// </summary> /// <param name="fileName">上传文件名</param> /// <param name="offSet">偏移</param> /// <param name="intoBuffer">每次上传字节数组 单位KB</param> /// <returns>上传是否成功</returns> [WebMethod] public bool Upload(string fileName, long offSet, byte[] intoBuffer) { //指定上传文件夹+文件名(相对路径) string strPath = "./Resources/" + fileName; //将相对路径转换成服务器的绝对路径 strPath = Server.MapPath(strPath); if (offSet < 0) { offSet = 0; } byte[] buffer = intoBuffer; if (buffer != null) { //读写文件的文件流,支持同步读写也支持异步读写 FileStream filesStream = new FileStream(strPath, FileMode.OpenOrCreate, FileAccess.ReadWrite); filesStream.Seek(offSet, SeekOrigin.Begin); filesStream.Write(buffer, 0, buffer.Length); filesStream.Flush(); filesStream.Close(); filesStream.Dispose(); return true; } return false; } } }
客户端代码,后台:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.IO; using System.Collections; using System.Windows.Data; using System.Xml; namespace SilverlightApplication6 { public partial class MainPage : UserControl { #region 类变量 List<FilesClass> fl = new List<FilesClass>(); System.IO.FileStream str = null; ServiceReference1.WebService1SoapClient x = new SilverlightApplication6.ServiceReference1.WebService1SoapClient(); FilesClass obj = null; byte[] by = null; int iFileCount = 1; int offset = 0; double current = 0; int currentFileNum = 0; #endregion #region 事件 public MainPage() { InitializeComponent(); } private void Mybutton_Click(object sender, RoutedEventArgs e) { OpenFileDialog op = new OpenFileDialog(); op.Multiselect = true; op.ShowDialog(); if (op.Files != null) { foreach (FileInfo f in op.Files) { if (f.Length < 1048576000) { FilesClass obj = new FilesClass(); obj.PropFileName = f; obj.PropNumber = iFileCount.ToString(); fl.Add(obj); iFileCount++; } else { MessageBox.Show("Max file size is 1 MB"); } } } else { MessageBox.Show("Select File"); } } private void MyReset_Click(object sender, RoutedEventArgs e) { fl.Clear(); iFileCount = 1; progFile2.Value = 0; } private void Upload_Click(object sender, RoutedEventArgs e) { UpLoadStart(0); } #endregion #region 私有函数 private void UpLoadStart(int fileNum) { try { x.UploadCompleted += new EventHandler<SilverlightApplication6.ServiceReference1.UploadCompletedEventArgs>(x_UploadCompleted); if (fileNum == 0) currentFileNum = 0; if (fl.Count > 0 && fl.Count > fileNum) { obj = (FilesClass)fl[fileNum]; str = obj.PropFileName.OpenRead(); progFile2.Maximum = (double)(str.Length); UpLoadStep(); } } catch { throw; } } private void UpLoadStep() { try { if (str.Length - current > 10240) { offset = 10240; by = new byte[offset]; str.Read(by, 0, offset); current = (double)(str.Position); x.UploadAsync(obj.PropFileName.Name, str.Position - offset, by); } else { offset = (int)(str.Length - str.Position); by = new byte[offset]; str.Read(by, 0, offset); current = (double)(str.Length); x.UploadAsync(obj.PropFileName.Name, str.Position - offset, by); } } catch { throw; } } void x_UploadCompleted(object sender, SilverlightApplication6.ServiceReference1.UploadCompletedEventArgs e) { if (e.Result != true) { MessageBox.Show("上传失败,请重新上传!"); } this.rre.Text = "" + e.Result.ToString(); progFile2.Value = current; if (current == str.Length) { x.UploadCompleted -= this.x_UploadCompleted; str.Flush(); str.Close(); str.Dispose(); fl[currentFileNum].PropStatus = "上传成功!"; //BindGrid(); currentFileNum++; offset = 0; current = 0; if (fl.Count > currentFileNum) { UpLoadStart(currentFileNum); } else { //MessageBox.Show("all end!"); return; } } UpLoadStep(); } #endregion } }
前台:
<UserControl x:Class="SilverlightApplication6.MainPage" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" 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" d:DesignWidth="640" d:DesignHeight="480"> <Grid x:Name="LayoutRoot" Background="YellowGreen" ShowGridLines="True" > <Grid.RowDefinitions> <RowDefinition Height="535"></RowDefinition> <RowDefinition Height="30"></RowDefinition> <RowDefinition Height="35"></RowDefinition> <RowDefinition Height="35"></RowDefinition> </Grid.RowDefinitions> <StackPanel Grid.Row="2" Orientation="Horizontal" > <Button Content="选择上传文件" x:Name="MyButton" Width="100" Height="20" Click="Mybutton_Click" Grid.Column="0" FontSize="12"></Button> <Button Content="清除" x:Name="MyReset" Width="100" Height="20" Click="MyReset_Click" Grid.Column="1" FontSize="12"></Button> <Button Content="上传" x:Name="Upload" Width="100" Height="20" Click="Upload_Click" Grid.Column="2" FontSize="12"></Button> </StackPanel> <StackPanel Grid.Row="1" VerticalAlignment="Center"> <ProgressBar Name="progFile2" Height="20" Width="600"></ProgressBar> </StackPanel> <TextBlock x:Name="rre" Width="200" Grid.Row="0"></TextBlock> </Grid> </UserControl>