Silverlight WebClient 上传实现

之前讨论过了 Silverlight通过 WCF实现上传的方法,现在看看另一种Silverlight实现上传的方法 :WebClient类实现上传,同时WEBCLIENT的 OPENWRITE也是官方提供的通常的上传方式,因为他完全就是HTTP实现上传的原本模式,及建立HTTP连接,打开一个可写入流,然后将文件流写入到HTTP写入流中实现,而WCF是通过传递字节数组参数的方法,两则之间看似差不多,实际上工作原理很不同。

 

webclient类中有几个方法,其中大部分都是请求获取相应流,只有openwrite方法是写入流。所以我们使用该方法实现上传。

 

工作方式:

Silverlight打开文件,获取文件流,webclient 调用openwrite方法,请求服务器,打开一个可以写入流 InputStream

当该可写入流可用的时候,相应openwrite异步方法的一个回调事件,在该事件中将文件流写入到HTTP的可写入流。服务器端接收到输入流后写入到文件流保存。

 

服务器端:(我擦用ASHX作为服务器端接收页,因为我们不需要返回什么信息,只接受请求,所以没用ASPX页,不过要使用ASPX也可以)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Services;

using System.IO;

 

namespace WebApp4SL

{

    /// <summary>

    /// $codebehindclassname$ 的摘要说明

    /// </summary>

    [WebService(Namespace = "http://tempuri.org/")]

    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

    public class WebClientUpload : IHttpHandler

    {

 

        public void ProcessRequest(HttpContext context)

        {

 

            Stream s = context.Request.InputStream;

 

            FileStream fs = new FileStream(context.Server.MapPath("UploadFile") + "/" + "asdf.jpg",FileMode.Create);

 

            byte[] bytes = new byte[s.Length];

 

            s.Read(bytes,0,bytes.Length);

 

            fs.Write(bytes,0,bytes.Length);

 

            fs.Flush();

 

            fs.Close();

                       

        }

 

        public bool IsReusable

        {

            get

            {

                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;

 

namespace SilverlightTest

{

    public partial class WebClientUpLoad : UserControl

    {

        public WebClientUpLoad()

        {

            InitializeComponent();

        }

 

        private void openfile_Click(object sender, RoutedEventArgs e)

        {

            OpenFileDialog op = new OpenFileDialog();

 

 

            if (op.ShowDialog() == true)

            {

                FileStream fs = op.File.OpenRead();

 

 

                WebClient wc = new WebClient();

 

                wc.OpenWriteCompleted += new OpenWriteCompletedEventHandler(wc_OpenWriteCompleted);

 

                wc.OpenWriteAsync(new Uri("WebClientUpload.ashx",UriKind.Relative),"POST",fs);

 

               

            }

 

        }

 

        void wc_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)

        {

            try

            {

                Stream fs = (Stream)e.UserState;

                Stream inputstream = e.Result;

 

 

 

                byte[] bytes = new byte[fs.Length];

 

                fs.Read(bytes, 0, bytes.Length);

 

                inputstream.Write(bytes, 0, bytes.Length);

 

               

 

                inputstream.Close();

                fs.Close();

 

            }

            catch

            {

                info.Text = e.Error.InnerException.Message;

            }

        }

    }

}

 

界面:(实在献丑,界面基本上就个按钮会用到,因为只是为了说明WEBCLIENT的上传,所以没做什么界面上的开发)

<UserControl x:Class="SilverlightTest.WebClientUpLoad"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Width="400" Height="300">

    <Grid x:Name="LayoutRoot" Background="White">

    <Button Height="24" Margin="0,8,8,0" VerticalAlignment="Top" Content="浏览" Width="69" HorizontalAlignment="Right" x:Name="openfile" Click="openfile_Click" />

    <TextBlock Height="24" Margin="8,8,81,0" VerticalAlignment="Top" Text="请选择文件" TextWrapping="Wrap" x:Name="filepath"/>

    <TextBlock Margin="8,51,8,0" Text="" TextWrapping="Wrap" VerticalAlignment="Top" Height="96" x:Name="info"/>

 

    </Grid>

</UserControl>

 

 

 

WEBCLIENT 的OPENWRITE还有个UploadProgressChanged事件,该事件指定好对应的处理函数后还可以用来获取上传进度,所以用webclient来实现上传还是非常方便的,与WCF比较起来,WCF可以自由的设置参数,但是WCF的字节数组参数长度是有限制的虽然可以在WEBCONFIG里进行设置,但是WCF实现上传不是官方提供的解决方案;Webclient 的Openwrite方法是官方提供的文件上传解决方案,工作原理继承传统的HTTP文件上传,同时由于发起读取文件写入流都是在客户端异步进行,所以,及时要实现分块也非常容易(webclient的其他大部分方法不允许在之前的请求没完成前进行第2次请求,但是openwrite的文档中没用说明限制,我自己也没实验过,51过后再研究),但是webclient请求服务器传递参数上不够灵活,部署方面也没有WCF那么松散,所以WCF上传和webclient上传都是可行的,但是具体项目具体分析,采取最好的最适当的方式实现。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
<script type="text/C#" runat="server"> BinaryReader ms; UploadInfo uploadInfo = null; protected void Page_Load(object sender, EventArgs args) { if (this.IsPostBack) { uploadInfo = this.Session["UploadInfo"] as UploadInfo; if (uploadInfo == null) { // 让父页面知道无法处理上传 const string js = "window.parent.onComplete('error', '无法上传文件。请刷新页面,然后再试一次);"; ScriptManager.RegisterStartupScript(this, typeof(upload_aspx), "progress", js, true); } else { // 让服务端知道我们还没有准备好.. uploadInfo.IsReady = false; try { // 读取要上传的文件 FileStream fs = new FileStream(this.fileUpload.PostedFile.FileName, FileMode.Open, FileAccess.Read); ms = new BinaryReader(fs); string newFile = DateTime.Now.Ticks.ToString(); string exit = this.fileUpload.FileName.Substring(this.fileUpload.FileName.IndexOf('.')); newFile = newFile + exit; UriBuilder url = new UriBuilder("http://192.168.25.27:8056/UploadFileHander.ashx");//上传路径 url.Query = string.Format("filename={0}", newFile);//上传url参数 uploadInfo.ContentLength = this.fileUpload.PostedFile.ContentLength; uploadInfo.FileName = newFile; uploadInfo.UploadedLength = 0; //文件存在 初始化... uploadInfo.IsReady = true; WebClient wc = new WebClient(); wc.Credentials = CredentialCache.DefaultCredentials; wc.OpenWriteCompleted += new OpenWriteCompletedEventHandler(wc_OpenWriteCompleted);//委托异步上传事件 wc.OpenWriteAsync(url.Uri);//开始异步上传 const string js = "window.parent.onComplete('success', '{0} 已成功上传,重命名为:{1}:文件大小:{2}');"; ScriptManager.RegisterStartupScript(this, typeof(upload_aspx), "progress", string.Format(js, Path.GetFileName(this.fileUpload.FileName), DateTime.Now.ToString("yyyy-MM") + "/" + DateTime.Now.Day + "/" + newFile, uploadInfo.ContentLength), true); } catch (Exception ex) { Response.Write(ex.Message); } } } } protected void wc_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e) { int bufSize = 10; int byteGet = 0; byte[] buf = new byte[bufSize]; while ((byteGet = ms.Read(buf, 0, bufSize)) > 0)//循环读取,上传 { e.Result.Write(buf, 0, byteGet);//注意这里 uploadInfo.UploadedLength += byteGet; } // 让父页面知道已经处理上传完毕 e.Result.Close();//关闭 ms.Close(); } </script>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值