为了节省大家时间,先看怎么使用,最后再贴代码:
截图如下:我把这个功能做成了一个控件,大家直接在要用的页面调用就行,在网站根目录web.config里配置上传文件夹,注意:folder的value要写成windows资源管理器形式例如:
upload\audio\chenxumi,而且是相对网站根目录而言。因为这里是分块上传的每块大小为4MB。所以maxRequestLength设为4100kb,至于为什么不是4096kb是因为上传时还附带了很多其他信息,例如当前文件的文件名、文件是否为第一次上传、文件是否是最后一块上传、文件此时的偏移量等信息,显然这种最大上传限制很有弹性,比起传统的一次性上传大小设置更有活性。
为了节省大家时间,先看怎么使用,最后再贴代码:
截图如下:
![](https://images.cnblogs.com/cnblogs_com/chenxumi/1.JPG)
![](https://images.cnblogs.com/cnblogs_com/chenxumi/2.JPG)
我把这个功能做成了一个控件,大家直接在要用的页面调用就行
<%@ Register Src="~/SLUpload/SLUpload.ascx" TagName="Upload" TagPrefix="u"%>
<u:Upload runat=server ></u:Upload>
在网站根目录web.config里配置上传文件夹,注意:folder的value要写成windows资源管理器形式例如:
upload\audio\chenxumi,而且是相对网站根目录而言。因为这里是分块上传的每块大小为4MB。所以maxRequestLength设为4100kb,至于为什么不是4096kb是因为上传时还附带了很多其他信息,例如当前文件的文件名、文件是否为第一次上传、文件是否是最后一块上传、文件此时的偏移量等信息,显然这种最大上传限制很有弹性,比起传统的一次性上传大小设置更有活性。
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="SLUpload" type="System.Configuration.NameValueSectionHandler"/>
</configSections>
<SLUpload>
<add key="folder" value="upload"/>
</SLUpload>
<system.web>
<httpRuntime maxRequestLength="4050"/>
<compilation debug="true"/></system.web>
</configuration>
大家测试时有可能会出现文件无法上传的现象,这是在服务器后面又加别名导致FileReceive.ashx的路径错误。
从IIS里打开就可以解决这个问题。
文件下载地址:
https://files.cnblogs.com/chenxumi/sl.rar
这个程序的界面设计用的是Blend,只需改变KeyTime的value就可以,具体怎么做,给大家推荐一个视频,
本来要贴视频地址的,但是silverlight.net网站打开的慢如蜗牛,大家有机会上去看看,有个动态改变keyframe的
value的一个动画
程序设计方面其实很简单,大家知道原理就行,把文件分成4mb大小的块,在发送一次文件时除发送文件的
本身数据流外,还得发送其他附加信息,例如文件名、文件此时的偏移量、是否是最后还是第一次到达,然后后台
接受文件的程序再根据这些信息先生成一个临时文件,如果此时文件存在则会删除文件,如果此时发送的文件是
最后一块时就将临时文件转移到目标文件夹中也就是web.config里配置的文件夹里。
这里还有个小问题大家注意,因为从服务器返回的响应和主程序是异步的,所以当返回后是不能调用主线程的,即不能
修改文件上传的界面,所以这里用到了线程的队列服务这个类 Dispatcher 具体代码请见如下:
public Dispatcher UIDispatcher;
while (--)
{
requestStream.Write(buffer, 0, bytesRead);
requestStream.Flush();
send += bytesRead;
tempTotal += bytesRead;
this.UIDispatcher.BeginInvoke(delegate()
{
OnProgressChanged();
});
}
文件选定、文件发送、以及服务器回调函数、以及进度变化都是些很简单的方法,大家看看就行了
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
Code
private void btnUpLoad_Click(object sender, System.Windows.RoutedEventArgs e)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
OpenFileDialog dialog = new OpenFileDialog()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Filter = "all files|*.*",
Multiselect = false
};
if ((bool)dialog.ShowDialog())
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
send = 0;
data = dialog.File.OpenRead();
filename = dialog.File.Name;
UIDispatcher = this.Dispatcher;
this.UIDispatcher.BeginInvoke(delegate()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (keyframe_rect.Value.Equals(270))
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
keyframe_rect.Value = -270;
txbPrecent.Text = "0%";
keyframe_rect.KeyTime = System.Windows.Media.Animation.KeyTime.FromTimeSpan(TimeSpan.Zero);
Storyboard1.Begin();
}
});
StartUpload();
}
}
private void StartUpload()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
double dataToSend = data.Length - send;
bool isLastChunk = dataToSend <= ChunkSize;
bool isFirstChunk = send == 0;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
UriBuilder httpHandlerUrlBuilder = new UriBuilder(new Uri(this.url, UriKind.Absolute));
httpHandlerUrlBuilder.Query = string.Format("{5}file={0}&offset={1}&last={2}&first={3}¶m={4}", filename, send, isLastChunk, isFirstChunk, "", string.IsNullOrEmpty(httpHandlerUrlBuilder.Query) ? "" : httpHandlerUrlBuilder.Query.Remove(0, 1) + "&");
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(httpHandlerUrlBuilder.Uri);
webRequest.Method = "POST";
webRequest.BeginGetRequestStream(new AsyncCallback(WriteToStreamCallback), webRequest);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
private void WriteToStreamCallback(IAsyncResult asynchronousResult)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
Stream requestStream = webRequest.EndGetRequestStream(asynchronousResult);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
byte[] buffer = new Byte[4096];
int bytesRead = 0;
int tempTotal = 0;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
while (tempTotal + bytesRead < ChunkSize && (bytesRead = data.Read(buffer, 0, buffer.Length)) != 0
)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
requestStream.Write(buffer, 0, bytesRead);
requestStream.Flush();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
send += bytesRead;
tempTotal += bytesRead;
this.UIDispatcher.BeginInvoke(delegate()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
OnProgressChanged();
});
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
requestStream.Close();
webRequest.BeginGetResponse(new AsyncCallback(ReadHttpResponseCallback), webRequest);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
private void ReadHttpResponseCallback(IAsyncResult asynchronousResult)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse webResponse = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string responsestring = reader.ReadToEnd();
reader.Close();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (send < data.Length)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
StartUpload();
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
data.Close();
data.Dispose();
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
private void OnProgressChanged()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
double progress = send / (double)(data.Length);
keyframe_rect.Value = (double)progress * 270;
txbPrecent.Text = (send / 1024 / 1024).ToString("0.0").Replace(".0", "") + "MB " + (progress * 100).ToString("0.0").Replace(".0", "") + "%";
Storyboard1.Begin();
}