webclient上传:Silverlight(20) - 2.0通信的WebClient 以字符串的形式上传/下载数据 以流的方式上传/下载数据

  本文源代码下载地址:

  http://flashview.ddvip.com/2008_12/Silverlight.rar 

  介绍

  Silverlight 2.0 详解WebClient形式上传、下载数据;以流方式上传、下载数据

  WebClient - 将数据发送到指定 URI或者从指定 URI 接收数据

  DownloadStringAsync(Uri address, Object userToken) - 以形式下载指定 URI 资源

  UploadStringAsync(Uri address, data) - 以形式上传数据到指定 URI所使用 HTTP 思路方法默认为 POST

  OpenReadAsync(Uri address, Object userToken) - 以流形式下载指定 URI 资源

  OpenWriteAsync(Uri address, method, Object userToken) - 打开流以使用指定思路方法向指定 URI 写入数据

  在线DEMO

  http://www.cnblogs.com/webabcd/archive/2008/10/09/1307486.html

  举例

  1、以形式和流形式下载数据

  WebClientDownload.xaml

<UserControl x:Class="Silverlight20.Communication.WebClientDownload"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
    <StackPanel Margin="5" Width="200">
      <TextBox x:Name="lblMsgString" Margin="5" />
      <ProgressBar x:Name="progressBarString" Height="20" Margin="5" Minimum="0" Maximum="100" />
    </StackPanel>
    <StackPanel Margin="5" Width="200">
      <TextBox x:Name="lblMsgStream" Margin="5" />
      <ProgressBar x:Name="progressBarStream" Height="20" Margin="5" Minimum="0" Maximum="100" />
      <Image x:Name="img" Margin="5" />
    </StackPanel>
  </StackPanel>
</UserControl>


  WebClientDownload.xaml.cs

using ;
using .Collections.Generic;
using .Linq;
using .Net;
using .Windows;
using .Windows.Controls;
using .Windows.Documents;
using .Windows.Input;
using .Windows.Media;
using .Windows.Media.Animation;
using .Windows.Shapes;
using .IO;
Silverlight20.Communication
{
  public partial WebClientDownload : UserControl
  {
    // 用于演示以形式下载数据
     _urlString = "http://localhost/Files/Demo.zip";
    // 用于演示以流形式下载数据
     _urlStream = "http://localhost/Files/Logo.png";
    public WebClientDownload
    {
      InitializeComponent;
      // 演示串式下载
      DownloadStringDemo;
      // 演示流式下载
      DownloadStreamDemo;
    }
    /**//// <summary>
    /// 演示串式下载
    /// </summary>
    void DownloadStringDemo
    {
      Uri uri = Uri(_urlString, UriKind.Absolute);
      /**//*
       * WebClient - 将数据发送到指定 URI或者从指定 URI 接收数据
       *   DownloadStringCompleted - 下载数据完毕后(包括取消操作及有发生时)所触发事件
       *   DownloadProgressChanged - 下载数据过程中所触发事件正在下载或下载完全部数据后会触发
       *   DownloadStringAsync(Uri address, Object userToken) - 以形式下载指定 URI 资源
       *     Uri address - 需要下载资源地址
       *     Object userToken - 用户标识
       */
      .Net.WebClient clientDownloadString = .Net.WebClient;
      clientDownloadString.DownloadStringCompleted DownloadStringCompletedEventHandler(clientDownloadString_DownloadStringCompleted);
      clientDownloadString.DownloadProgressChanged DownloadProgressChangedEventHandler(clientDownloadString_DownloadProgressChanged);
      clientDownloadString.DownloadStringAsync(uri, "userToken");
    }
    void clientDownloadString_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
      /**//*
       * DownloadProgressChangedEventArgs.ProgressPercentage - 下载完成百分比
       * DownloadProgressChangedEventArgs.BytesReceived - 当前收到字节数
       * DownloadProgressChangedEventArgs.TotalBytesToReceive - 总共需要下载字节数
       * DownloadProgressChangedEventArgs.UserState - 用户标识
       */
      lblMsgString.Text = .Format("下载完成百分比:{0}rn当前收到字节数:{1}rn总共需要下载字节数:{2}rn",
        e.ProgressPercentage. + "%",
        e.BytesReceived.,
        e.TotalBytesToReceive.);
      progressBarString.Value = (double)e.ProgressPercentage;
    }
    void clientDownloadString_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
      /**//*
       * DownloadStringCompletedEventArgs.Error - 该异步操作期间是否发生了
       * DownloadStringCompletedEventArgs.Cancelled - 该异步操作是否已被取消
       * DownloadStringCompletedEventArgs.Result - 下载后串类型数据
       * DownloadStringCompletedEventArgs.UserState - 用户标识
       */
       (e.Error != null)
      {
        lblMsgString.Text e.Error.;
        ;
      }
       (e.Cancelled != true)
      {
        lblMsgString.Text .Format("用户标识:{0}", e.UserState.);
      }
    }
  
    /**//// <summary>
    /// 演示流式下载
    /// </summary>
    void DownloadStreamDemo
    {
      Uri uri = Uri(_urlStream, UriKind.Absolute);
      /**//*
       * WebClient - 将数据发送到指定 URI或者从指定 URI 接收数据
       *   IsBusy - 指定web请求是否正在进行中
       *   CancelAsync - 取消指定异步操作
       *   OpenReadCompleted - 数据读取完毕后(包括取消操作及有发生时)所触发事件方式
       *   DownloadProgressChanged - 下载数据过程中所触发事件正在下载或下载完全部数据后会触发
       *   OpenReadAsync(Uri address, Object userToken) - 以流形式下载指定 URI 资源
       *     Uri address - 需要下载资源地址
       *     Object userToken - 用户标识
       */
      .Net.WebClient clientDownloadStream = .Net.WebClient;
       (clientDownloadStream.IsBusy)
        clientDownloadStream.CancelAsync;
      clientDownloadStream.OpenReadCompleted OpenReadCompletedEventHandler(clientDownloadStream_OpenReadCompleted);
      clientDownloadStream.DownloadProgressChanged DownloadProgressChangedEventHandler(clientDownloadStream_DownloadProgressChanged);
      clientDownloadStream.OpenReadAsync(uri);
    }
    void clientDownloadStream_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
      /**//*
       * DownloadProgressChangedEventArgs.ProgressPercentage - 下载完成百分比
       * DownloadProgressChangedEventArgs.BytesReceived - 当前收到字节数
       * DownloadProgressChangedEventArgs.TotalBytesToReceive - 总共需要下载字节数
       * DownloadProgressChangedEventArgs.UserState - 用户标识
       */
      lblMsgString.Text = .Format("下载完成百分比:{0}rn当前收到字节数:{1}rn总共需要下载字节数:{2}rn",
        e.ProgressPercentage. + "%",
        e.BytesReceived.,
        e.TotalBytesToReceive.);
      progressBarStream.Value = (double)e.ProgressPercentage;
    }
    void clientDownloadStream_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
      /**//*
       * OpenReadCompletedEventArgs.Error - 该异步操作期间是否发生了
       * OpenReadCompletedEventArgs.Cancelled - 该异步操作是否已被取消
       * OpenReadCompletedEventArgs.Result - 下载后 Stream 类型数据
       * OpenReadCompletedEventArgs.UserState - 用户标识
       */
       (e.Error != null)
      {
        lblMsgStream.Text e.Error.;
        ;
      }
       (e.Cancelled != true)
      {
        .Windows.Media.Imaging.BitmapImage imageSource = .Windows.Media.Imaging.BitmapImage;
        imageSource.SetSource(e.Result);
        img.Source = imageSource;
      }
    }
  }
}


  2、以形式和流形式上传数据

  REST.cs(WCF创建用于演示以形式和流形式上传数据REST服务)

using ;
using .Linq;
using .Runtime.Serialization;
using .ServiceModel;
using .ServiceModel.Activation;
using .ServiceModel.Web;
using .Collections.Generic;
using .Text;
using .IO;
/**//// <summary>
/// 提供 REST 服务
/// 注:Silverlight只支持 GET 和 POST
/// </summary>
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public REST
{
  /**//// <summary>
  /// 用于演示返回 JSON(对象) REST 服务
  /// </summary>
  /// <param name="name"></param>
  /// <s></s>
  [OperationContract]
  [WebGet(UriTemplate = "User/{name}/json", ResponseFormat = WebMessageFormat.Json)]
  public User HelloJson( name)
  {
     User { Name = name, DayOfBirth = DateTime(1980, 2, 14) };
  }
  /**//// <summary>
  /// 用于演示返回 JSON(集合) REST 服务
  /// </summary>
  /// <s></s>
  [OperationContract]
  [WebGet(UriTemplate = "Users/json", ResponseFormat = WebMessageFormat.Json)]
  public List<User> HelloJson2
  {
     List<User>
    {
       User{ Name = "webabcd01", DayOfBirth = DateTime(1980, 1, 1) },
       User{ Name = "webabcd02", DayOfBirth = DateTime(1980, 2, 2) },
       User{ Name = "webabcd03", DayOfBirth = DateTime(1980, 3, 3) },
    };
  }
  /**//// <summary>
  /// 用于演示返回 XML(对象) REST 服务
  /// </summary>
  /// <param name="name"></param>
  /// <s></s>
  [OperationContract]
  [WebGet(UriTemplate = "User/{name}/xml", ResponseFormat = WebMessageFormat.Xml)]
  public User HelloXml( name)
  {
     User { Name = name, DayOfBirth = DateTime(1980, 2, 14) };
  }
  /**//// <summary>
  /// 用于演示返回 XML(集合) REST 服务
  /// </summary>
  /// <s></s>
  [OperationContract]
  [WebGet(UriTemplate = "Users/xml", ResponseFormat = WebMessageFormat.Xml)]
  public List<User> HelloXml2
  {
     List<User>
    {
       User{ Name = "webabcd01", DayOfBirth = DateTime(1980, 1, 1) },
       User{ Name = "webabcd02", DayOfBirth = DateTime(1980, 2, 2) },
       User{ Name = "webabcd03", DayOfBirth = DateTime(1980, 3, 3) },
    };
  }
  /**//// <summary>
  /// 用于演示以形式上传数据 REST 服务
  /// </summary>
  /// <param name="fileName">上传文件名</param>
  /// <param name="stream">POST 过来数据</param>
  /// <s></s>
  [OperationContract]
  [WebInvoke(UriTemplate = "UploadString/?fileName={fileName}", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
  public bool UploadString( fileName, Stream stream)
  {
    // 文件服务端保存路径
     path = Path.Combine("C:", fileName);
    try
    {
      using (StreamReader sr = StreamReader(stream))
      {
        // 将 POST 过来被 Base64 编码过串传换成
         buffer = Convert.FromBase64String(sr.ReadToEnd);
        using (FileStream fs = FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
        {
          // 将文件写入到服务端
          fs.Write(buffer, 0, buffer.Length);
        }
      }
       true;
    }
    catch
    {
       false;
    }
  }
  /**//// <summary>
  /// 用于演示以流形式上传数据 REST 服务
  /// </summary>
  /// <param name="fileName">上传文件名</param>
  /// <param name="stream">POST 过来数据(流方式)</param>
  /// <s></s>
  [OperationContract]
  [WebInvoke(UriTemplate = "UploadStream/?fileName={fileName}", Method = "POST", ResponseFormat = WebMessageFormat.Json)]
  public bool UploadStream( fileName, Stream stream)
  {
    // 文件服务端保存路径
     path = Path.Combine("C:", fileName);
    try
    {
      using (FileStream fs = FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
      {
         buffer = [4096];
         count = 0;
        // 每 POST 过来 4096 字节数据往服务端写
        while ((count = stream.Read(buffer, 0, buffer.Length)) > 0)
        {
          fs.Write(buffer, 0, count);
        }
      }
       true;
    }
    catch
    {
       false;
    }
  }
}


  WebClientUpload.xaml

<UserControl x:Class="Silverlight20.Communication.WebClientUpload"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">   
    <StackPanel Margin="5" Width="200">
      <TextBox x:Name="lblMsgString" Margin="5" />
      <ProgressBar x:Name="progressBarString" Height="20" Margin="5" Minimum="0" Maximum="100" />
      <Button x:Name="btnString" Content="上传文件(方式)" Margin="5" Click="btnString_Click" />
    </StackPanel>
    <StackPanel Margin="5" Width="200">
      <TextBox x:Name="lblMsgStream" Margin="5" />
      <ProgressBar x:Name="progressBarStream" Height="20" Margin="5" Minimum="0" Maximum="100" />
      <Button x:Name="btnStream" Content="上传文件(流方式)" Margin="5" Click="btnStream_Click" />
    </StackPanel>
  </StackPanel>
</UserControl>


  WebClientUpload.xaml.cs

using ;
using .Collections.Generic;
using .Linq;
using .Net;
using .Windows;
using .Windows.Controls;
using .Windows.Documents;
using .Windows.Input;
using .Windows.Media;
using .Windows.Media.Animation;
using .Windows.Shapes;
using .IO;
using .Windows.Resources;
using .ComponentModel;
using .Windows.Browser;
Silverlight20.Communication
{
  public partial WebClientUpload : UserControl
  {
    // 用于演示以形式上传数据
     _urlString = "http://localhost:3036/REST.svc/UploadString/?fileName=";
    // 用于演示以流形式上传数据
     _urlStream = "http://localhost:3036/REST.svc/UploadStream/?fileName=";
    public WebClientUpload
    {
      InitializeComponent;
    }
    /**//// <summary>
    /// 演示串式上传
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnString_Click(object sender, RoutedEventArgs e)
    {
       data = "";
      /**//*
       * OpenFileDialog - 文件对话框
       *   ShowDialog - 显示文件对话框在文件对话框中单击“确定”则返回true反的则返回false
       *   File - 所选文件 FileInfo 对象
       */
      OpenFileDialog dialog = OpenFileDialog;
       (dialog.ShowDialog true)
      {
        using (FileStream fs = dialog.File.OpenRead)
        {
           buffer = [fs.Length];
          fs.Read(buffer, 0, buffer.Length);
          // 将指定 转换为串(使用Base64编码)
          data = Convert.ToBase64String(buffer);
        }
        /**//*
         * WebClient - 将数据发送到指定 URI或者从指定 URI 接收数据
         *   UploadStringCompleted - 上传数据完毕后(包括取消操作及有发生时)所触发事件
         *   UploadProgressChanged - 上传数据过程中所触发事件正在上传或上传完全部数据后会触发
         *   Headers - 和请求相关标头 key/value 对集合
         *   UploadStringAsync(Uri address, data) - 以形式上传数据到指定 URI所使用 HTTP 思路方法默认为 POST
         *     Uri address - 接收上传数据 URI
         *     data - 需要上传数据
         */
        .Net.WebClient clientUploadString = .Net.WebClient;
        clientUploadString.UploadStringCompleted UploadStringCompletedEventHandler(clientUploadString_UploadStringCompleted);
        clientUploadString.UploadProgressChanged UploadProgressChangedEventHandler(clientUploadString_UploadProgressChanged);
        Uri uri = Uri(_urlString + dialog.File.Name, UriKind.Absolute);
        clientUploadString.Headers["Content-Type"] = "application/x-www-form-urlencoded";
        clientUploadString.UploadStringAsync(uri, data);
      }
    }
    void clientUploadString_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
    {
      /**//*
       * UploadProgressChangedEventArgs.ProgressPercentage - 上传完成百分比
       * UploadProgressChangedEventArgs.BytesSent - 当前发送字节数
       * UploadProgressChangedEventArgs.TotalBytesToSend - 总共需要发送字节数
       * UploadProgressChangedEventArgs.BytesReceived - 当前接收字节数
       * UploadProgressChangedEventArgs.TotalBytesToReceive - 总共需要接收字节数
       * UploadProgressChangedEventArgs.UserState - 用户标识
       */
      lblMsgString.Text = .Format("上传完成百分比:{0}rn当前发送字节数:{1}rn总共需要发送字节数:{2}rn当前接收字节数:{3}rn总共需要接收字节数:{4}rn",
        e.ProgressPercentage.,
        e.BytesSent.,
        e.TotalBytesToSend.,
        e.BytesReceived.,
        e.TotalBytesToReceive.);
      progressBarString.Value = (double)e.ProgressPercentage;
    }
    void clientUploadString_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
    {
      /**//*
       * UploadStringCompletedEventArgs.Error - 该异步操作期间是否发生了
       * UploadStringCompletedEventArgs.Cancelled - 该异步操作是否已被取消
       * UploadStringCompletedEventArgs.Result - 服务端返回数据(串类型)
       * UploadStringCompletedEventArgs.UserState - 用户标识
       */
       (e.Error != null)
      {
        lblMsgString.Text e.Error.;
        ;
      }
       (e.Cancelled != true)
      {
        var jsonObject = .Json.JsonObject.Parse(e.Result);
        lblMsgString.Text .Format("是否上传成功:{0}",
          (bool)jsonObject);
      }
    }
  
    /**//// <summary>
    /// 演示流式上传
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void btnStream_Click(object sender, RoutedEventArgs e)
    {
      FileStream fs = null;
      OpenFileDialog dialog = OpenFileDialog;
       (dialog.ShowDialog true)
      {
        fs = dialog.File.OpenRead;
        /**//*
         * WebClient - 将数据发送到指定 URI或者从指定 URI 接收数据
         *   OpenWriteCompleted - 在打开用于上传流完成时(包括取消操作及有发生时)所触发事件
         *   WriteStreamClosed - 在写入数据流异步操作完成时(包括取消操作及有发生时)所触发事件
         *   UploadProgressChanged - 上传数据过程中所触发事件如果 OpenWriteAsync 则不会触发此事件
         *   Headers - 和请求相关标头 key/value 对集合
         *   OpenWriteAsync(Uri address, method, Object userToken) - 打开流以使用指定思路方法向指定 URI 写入数据
         *     Uri address - 接收上传数据 URI
         *     method - 所使用 HTTP 思路方法(POST 或 GET)
         *     Object userToken - 需要上传数据流
         */
        .Net.WebClient clientUploadStream = .Net.WebClient;
        clientUploadStream.OpenWriteCompleted OpenWriteCompletedEventHandler(clientUploadStream_OpenWriteCompleted);
        clientUploadStream.UploadProgressChanged UploadProgressChangedEventHandler(clientUploadStream_UploadProgressChanged);
        clientUploadStream.WriteStreamClosed WriteStreamClosedEventHandler(clientUploadStream_WriteStreamClosed);
        Uri uri = Uri(_urlStream + dialog.File.Name, UriKind.Absolute);
        clientUploadStream.Headers["Content-Type"] = "multipart/form-data";
        clientUploadStream.OpenWriteAsync(uri, "POST", fs);
      }
    }
    void clientUploadStream_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)
    {
      // OpenWriteAsync所以不会触发 UploadProgressChanged 事件
      lblMsgString.Text = .Format("上传完成百分比:{0}rn当前发送字节数:{1}rn总共需要发送字节数:{2}rn当前接收字节数:{3}rn总共需要接收字节数:{4}rn",
        e.ProgressPercentage.,
        e.BytesSent.,
        e.TotalBytesToSend.,
        e.BytesReceived.,
        e.TotalBytesToReceive.);
      progressBarStream.Value = (double)e.ProgressPercentage;
    }
    void clientUploadStream_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
    {
      .Net.WebClient client = sender as .Net.WebClient;
       (e.Error != null)
      {
        lblMsgStream.Text e.Error.;
        ;
      }
       (e.Cancelled != true)
      {
        // e.UserState - 需要上传流(客户端流)
        Stream clientStream = e.UserState as Stream;
        // e.Result - 目标地址流(服务端流)
        Stream serverStream = e.Result;
         buffer = [4096];
         count = 0;
        // clientStream.Read - 将需要上传流读取到指定字节
        while ((count = clientStream.Read(buffer, 0, buffer.Length)) > 0)
        {
          // serverStream.Write - 将指定字节写入到目标地址
          serverStream.Write(buffer, 0, count);
        }
        serverStream.Close;
        clientStream.Close;
      }
    }
    void clientUploadStream_WriteStreamClosed(object sender, WriteStreamClosedEventArgs e)
    {
       (e.Error != null)
      {
        lblMsgStream.Text e.Error.;
        ;
      }
      
      {
        lblMsgStream.Text "上传完成";
      }
    }
  }
}
/**//*
* 其他:
* 1、WebClient 对象次只能启动个请求如果在个请求完成(包括出错和取消)前即IsBusy为true时进行第 2个请求则第 2个请求将会抛出 NotSupportedException 类型异常
* 2、如果 WebClient 对象 BaseAddress 属性不为空则 BaseAddress 和 URI(相对地址) 组合在起构成绝对 URI
* 3、WebClient 类 AllowReadStreamBuffering 属性:是否对从 Internet 资源接收数据做缓冲处理默认值为true将数据缓存Cache在客户端内存中以便随时被应用读取
*/




  OK



Tags:  silverlight.2.0 silverlight是什么 silverlight webclient上传

延伸阅读

最新评论

发表评论