网上找了很多Silverlight 带进度条的文件上传文章
要么就是已经封装好的控件,像
http://slfileupload.codeplex.com/releases/view/51136
要么就只有下载的进度显示的代码,郁闷啊!硬着头皮自己干吧!
<UserControl x:Class="Customization.MainPage"
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:DesignHeight="372" d:DesignWidth="582" xmlns:input="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input"
>
<Grid x:Name="LayoutRoot" Background="White">
<Button Content="上传图片" Height="23" HorizontalAlignment="Left" Margin="332,60,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button2_Click" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="116,60,0,0" Name="txtFilePath" VerticalAlignment="Top" Width="199" />
<Image Height="150" HorizontalAlignment="Left" Margin="115,108,0,0" Name="imgUpLoad" Stretch="Fill" VerticalAlignment="Top" Width="200" />
<ProgressBar Height="18" IsIndeterminate="False" Visibility="Collapsed" HorizontalAlignment="Left" Margin="116,26,0,0" Name="pbUpload" VerticalAlignment="Top" Width="199" />
</Grid>
</UserControl>
后端:
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.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Text;
using Customization.Annce;
using System.Net.Browser;
using System.Threading;
namespace Customization
{
public partial class MainPage : UserControl
{
public MainPage()
{
bool registerResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
bool httpsResult = WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);
InitializeComponent();
}
private UploadImgClient ui;
private byte[] buffer;
private int ChunkSize;
private int ChunkNum = 0;
private FileStream fsImg = null;
private void button2_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog pfDialog = new OpenFileDialog();
pfDialog.Filter = "图片文件 (*.bmp, *.jpg,*.png)|*.bmp;*.jpg;*.png";
if ((bool)pfDialog.ShowDialog())
{
BitmapImage bImg = new BitmapImage();
if (pfDialog.File != null)
{
fsImg = pfDialog.File.OpenRead();
ChunkSize = (int)fsImg.Length / 99;
bImg.SetSource(fsImg);
imgUpLoad.Source = bImg;
ui = new UploadImgClient();
buffer = new byte[ChunkSize];
fsImg.Position = 0;
ui.SendNameAndLengthCompleted+=new EventHandler<SendNameAndLengthCompletedEventArgs>(ui_SendNameAndLengthCompleted);
ui.SendImageByteCompleted += new EventHandler<SendImageByteCompletedEventArgs>(ui_SendImageByteCompleted);
ui.EndSaveImageCompleted+=new EventHandler<EndSaveImageCompletedEventArgs>(ui_EndSaveImageCompleted);
ui.SendNameAndLengthAsync(pfDialog.File.Name, (int)fsImg.Length);
pbUpload.Visibility = Visibility.Visible;
}
}
}
private void SendChunk()
{
fsImg.Read(buffer, 0, ChunkSize);
ui.SendImageByteAsync(buffer, ChunkNum);
}
public void ui_SendNameAndLengthCompleted(object o, SendNameAndLengthCompletedEventArgs e)
{
if (e.Result)
{
SendChunk();
}
else
{
MessageBox.Show("传输文件名和长度时出错!");
}
}
public void ui_SendImageByteCompleted(object o, SendImageByteCompletedEventArgs e)
{
if (pbUpload.Value==100)
{
ui.EndSaveImageAsync();
fsImg.Close();
return;
}
ChunkNum++;
pbUpload.Value = ChunkNum;
SendChunk();
}
public void ui_EndSaveImageCompleted(object o, EndSaveImageCompletedEventArgs e)
{
if (e.Result)
{
MessageBox.Show("图片上传成功!");
}
else
{
MessageBox.Show("图片上传出错!");
}
}
}
}
WEC SERVIES:
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.IO;
namespace Customization.Web
{
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class UploadImg
{
[OperationContract]
public bool SaveImage(byte[] imgBuffer, string fileName)
{
try
{
string root=System.Web.Hosting.HostingEnvironment.MapPath("~/");
string dayDire = string.Format("{0}UploadImage/{1}/", root, DateTime.Now.ToString("yyyy-MM-dd"));
if(!Directory.Exists(dayDire))
{
Directory.CreateDirectory(dayDire);
}
string fullPath = string.Format("{0}{1}{2}", dayDire, DateTime.Now.ToString("HHmmss"),fileName);
FileStream fs = new FileStream(fullPath, FileMode.Create, FileAccess.ReadWrite);
fs.Write(imgBuffer, 0, imgBuffer.Length);
fs.Flush();
fs.Close();
fileName = string.Empty;
bufferArray = null;
return true;
}
catch
{
return false;
}
}
private static byte[] bufferArray;
private static string fileName;
[OperationContract]
public bool SendNameAndLength(string _fileName, int length)
{
try
{
fileName = _fileName;
bufferArray = new byte[length];
return true;
}
catch
{
return false;
}
}
[OperationContract]
public int SendImageByte(byte[] buffer,int num)
{
if (bufferArray.Length > (num + 1) * buffer.Length)
{
for (int i = buffer.Length * num; i < (num + 1) * buffer.Length; i++)
{
bufferArray[i] = buffer[i - buffer.Length * num];
}
}
else
{
for (int i = buffer.Length * num; i < bufferArray.Length; i++)
{
bufferArray[i] = buffer[i - buffer.Length * num];
}
}
return num;
}
[OperationContract]
public bool EndSaveImage()
{
return SaveImage(bufferArray, fileName);
}
}
}
上传时文件分块传递,100块,再加上一点点代码,都可以支持断点续传了
数据不能再压缩,因为JPG本身已经压缩过了,如果有NB的压缩算法还是可以的
如果想提高性能,块数越少越好,不过这样进度条可就看不出效果了。
以上做法有点问题,因为在服务器端把图片数据存为static,那么就只能让一个人使用
要支持多人使用,把图片数据存在Session里
参考:
http://gregdoesit.com/2009/10/file-upload-in-silverlight-a-simple-solution/
玩技术,要学会忍受寂寞--