• Silverlight结合Web Service进行文件上传


    search了非常多的文章,总算勉强实现了。有许多不完善的地方。

    在HCLoad.Web项目下新建目录Pics复制一张图片到根目录下。

    图片名:Bubble.jpg 右击->属性->生成操作:Resource


    UC_UpDown.xaml

    复制代码
    大气象
    <UserControl x:Class="HCLoad.UC_UpDown"
        xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml" 
        Width
    ="500" Height="500">
        
    <StackPanel Background="White" Height="450">
            
    <Button Content="down" Click="Button_Click"></Button>
            
    <HyperlinkButton Content="下载保存" NavigateUri="http://localhost:4528/download.ashx?fileName=aa.txt" TargetName="_self" x:Name="lBtnDown" />
            
    <TextBlock x:Name="tbMsgString" Text="下载进度" TextAlignment="Center" Foreground="Green"></TextBlock>
            
    <Button x:Name="btnDownload" Content="DownLoad Pictures" Width="150" Height="35" Margin="15" Click="btnDownload_Click"/>
            
    <Border Background="Wheat" BorderThickness="5" Width="400" Height="280">
                
    <Image x:Name="imgDownLoad" Width="400" Height="300" Margin="15" Stretch="Fill"/>
            
    </Border>
            
    <Button x:Name="btnUpLoad" Content="UpLoad Pictures" Width="150" Height="35" Margin="15" Click="btnUpLoad_Click"/>
        
    </StackPanel>
    </UserControl>
    复制代码

    UC_UpDown.xaml.cs

    复制代码
    大气象
    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.Windows.Media.Imaging; //因为要使用BitmapImage
    using System.IO;  //因为要使用Stream

    namespace HCLoad
    {
        
    public partial class UC_UpDown : UserControl
        {
            
    //1、WebClient 对象一次只能启动一个请求。如果在一个请求完成(包括出错和取消)前,即IsBusy为true时,进行第二个请求,则第二个请求将会抛出 NotSupportedException 类型的异常
            
    //2、如果 WebClient 对象的 BaseAddress 属性不为空,则 BaseAddress 与 URI(相对地址) 组合在一起构成绝对 URI
            
    //3、WebClient 类的 AllowReadStreamBuffering 属性:是否对从 Internet 资源接收的数据做缓冲处理。默认值为true,将数据缓存在客户端内存中,以便随时被应用程序读取



            
    //获取选定图片信息
            System.IO.FileInfo fileinfo;
            
    public UC_UpDown()
            {
                InitializeComponent();
            }
            
    #region  下载图片
            
    private void btnDownload_Click(object sender, RoutedEventArgs e)
            {
                
    //向指定的Url发送下载流数据请求 
                String imgUrl = "http://localhost:4528/Bubble.jpg";
                Uri endpoint 
    = new Uri(imgUrl);

                WebClient client 
    = new WebClient();
                client.OpenReadCompleted 
    += new OpenReadCompletedEventHandler(OnOpenReadCompleted);
                client.DownloadProgressChanged 
    += new DownloadProgressChangedEventHandler(clientDownloadStream_DownloadProgressChanged);
                client.OpenReadAsync(endpoint);
            }
            
    void OnOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
            {

                
    //OpenReadCompletedEventArgs.Error - 该异步操作期间是否发生了错误
                
    //OpenReadCompletedEventArgs.Cancelled - 该异步操作是否已被取消
                
    //OpenReadCompletedEventArgs.Result - 下载后的 Stream 类型的数据
                
    //OpenReadCompletedEventArgs.UserState - 用户标识

                
    if (e.Error != null)
                {
                    MessageBox.Show(e.Error.ToString());
                    
    return;
                }
                
    if (e.Cancelled != true)
                {
                    
    //获取下载的流数据(在此处是图片数据)并显示在图片控件中
                    
    //Stream stream = e.Result;
                    
    //BitmapImage bitmap = new BitmapImage();
                    
    //bitmap.SetSource(stream);
                    
    //imgDownLoad.Source = bitmap;
                    Stream clientStream = e.UserState as Stream;
                    Stream serverStream 
    = (Stream)e.Result;
                    
    byte[] buffer = new byte[serverStream.Length];
                    serverStream.Read(buffer, 
    0, buffer.Length);
                    clientStream.Write(buffer, 
    0, buffer.Length);
                    clientStream.Close();
                    serverStream.Close();

                }



            }

            
    void clientDownloadStream_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
            {
                
    //DownloadProgressChangedEventArgs.ProgressPercentage - 下载完成的百分比
                
    //DownloadProgressChangedEventArgs.BytesReceived - 当前收到的字节数
                
    //DownloadProgressChangedEventArgs.TotalBytesToReceive - 总共需要下载的字节数
                
    //DownloadProgressChangedEventArgs.UserState - 用户标识

                
    this.tbMsgString.Text = string.Format("完成百分比:{0} 当前收到的字节数:{1} 资料大小:{2} ",
                  e.ProgressPercentage.ToString() 
    + "%",
                  e.BytesReceived.ToString(),
                  e.TotalBytesToReceive.ToString());

            }

            
    #endregion

            
    #region  上传图片
            
    private void btnUpLoad_Click(object sender, RoutedEventArgs e)
            {
                
    /**/
                
    /*
             *   OpenWriteCompleted - 在打开用于上传的流完成时(包括取消操作及有错误发生时)所触发的事件
             *   WriteStreamClosed - 在写入数据流的异步操作完成时(包括取消操作及有错误发生时)所触发的事件
             *   UploadProgressChanged - 上传数据过程中所触发的事件。如果调用 OpenWriteAsync() 则不会触发此事件
             *   Headers - 与请求相关的的标头的 key/value 对**
             *   OpenWriteAsync(Uri address, string method, Object userToken) - 打开流以使用指定的方法向指定的 URI 写入数据
             *     Uri address - 接收上传数据的 URI
             *     string method - 所使用的 HTTP 方法(POST 或 GET)
             *     Object userToken - 需要上传的数据流
             
    */


                OpenFileDialog openFileDialog 
    = new OpenFileDialog()
                {  
    //弹出打开文件对话框要求用户自己选择在本地端打开的图片文件
                    Filter = "Jpeg Files (*.jpg)|*.jpg|All Files(*.*)|*.*",
                    Multiselect 
    = false  //不允许多选 
                };

                
    if (openFileDialog.ShowDialog() == true)//.DialogResult.OK)
                {
                    
    //fileinfo = openFileDialog.Files; //取得所选择的文件,其中Name为文件名字段,作为绑定字段显示在前端
                    fileinfo = openFileDialog.File;

                    
    if (fileinfo != null)
                    {
                        WebClient webclient 
    = new WebClient();

                        
    string uploadFileName = fileinfo.Name.ToString(); //获取所选文件的名字

                        
    #region 把图片上传到服务器上

                        Uri upTargetUri 
    = new Uri(String.Format("http://localhost:4528/WebClientUpLoadStreamHandler.ashx?fileName={0}", uploadFileName), UriKind.Absolute); //指定上传地址

                        webclient.OpenWriteCompleted 
    += new OpenWriteCompletedEventHandler(webclient_OpenWriteCompleted);
                        webclient.Headers[
    "Content-Type"= "multipart/form-data";

                        webclient.OpenWriteAsync(upTargetUri, 
    "POST", fileinfo.OpenRead());
                        webclient.WriteStreamClosed 
    += new WriteStreamClosedEventHandler(webclient_WriteStreamClosed);

                        
    #endregion

                    }
                    
    else
                    {
                        MessageBox.Show(
    "请选取想要上载的图片!!!");
                    }
                }

            }



            
    void webclient_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
            {

                
    //将图片数据流发送到服务器上

                
    // e.UserState - 需要上传的流(客户端流)
                Stream clientStream = e.UserState as Stream;
                
    // e.Result - 目标地址的流(服务端流)
                Stream serverStream = e.Result;
                
    byte[] buffer = new byte[4096];
                
    int readcount = 0;
                
    // clientStream.Read - 将需要上传的流读取到指定的字节数组中
                while ((readcount = clientStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    
    // serverStream.Write - 将指定的字节数组写入到目标地址的流
                    serverStream.Write(buffer, 0, readcount);
                }
                serverStream.Close();
                clientStream.Close();


            }

            
    void webclient_WriteStreamClosed(object sender, WriteStreamClosedEventArgs e)
            {
                
    //判断写入是否有异常
                if (e.Error != null)
                {
                    System.Windows.Browser.HtmlPage.Window.Alert(e.Error.Message.ToString());
                }
                
    else
                {
                    System.Windows.Browser.HtmlPage.Window.Alert(
    "图片上传成功!!!");
                }
            }
            
    #endregion

            
    private void Button_Click(object sender, RoutedEventArgs e)
            {
                
    //这种方法搞不定,好像提示跨域操作。
                
    //提示:错误:Unhandled Error in Silverlight Application 跨线程访问无效。
                
    //Uri upTargetUri = new Uri(String.Format("http://localhost:4528/download.ashx?filename={0}", "123.jpg"), UriKind.Absolute); //指定上传地址
                
    //WebRequest request = WebRequest.Create(upTargetUri);
                
    //request.Method = "GET";
                
    //request.ContentType = "application/octet-stream";
                
    //request.BeginGetResponse(new AsyncCallback(RequestReady), request);

                
    //通过调用js代码下载,比较简单。
                System.Windows.Browser.HtmlPage.Window.Eval("window.location.href='http://localhost:4528/download.ashx?filename=123.jpg';");
            }
            
    void RequestReady(IAsyncResult asyncResult)
            {
                MessageBox.Show(
    "RequestComplete");
            }

        }
    }
    复制代码

    在HCLoad.Web项目下新建WebClientUpLoadStreamHandler.ashx

    复制代码
    大气象
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;

    using System.IO;  //因为要用到Stream

    namespace HCLoad.Web
    {
        
    public class WebClientUpLoadStreamHandler : IHttpHandler
        {

            
    public void ProcessRequest(HttpContext context)
            {
                
    //获取上传的数据流
                string fileNameStr = context.Request.QueryString["fileName"];
                Stream sr 
    = context.Request.InputStream;
                
    try
                {
                    
    string filename = "";

                    filename 
    = fileNameStr;

                    
    byte[] buffer = new byte[4096];
                    
    int bytesRead = 0;
                    
    //将当前数据流写入服务器端文件夹ClientBin下
                    string targetPath = context.Server.MapPath("Pics/" + filename + ".jpg");
                    
    using (FileStream fs = File.Create(targetPath, 4096))
                    {
                        
    while ((bytesRead = sr.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            
    //向文件中写信息
                            fs.Write(buffer, 0, bytesRead);
                        }
                    }

                    context.Response.ContentType 
    = "text/plain";
                    context.Response.Write(
    "上传成功");
                }
                
    catch (Exception e)
                {
                    context.Response.ContentType 
    = "text/plain";
                    context.Response.Write(
    "上传失败, 错误信息:" + e.Message);
                }
                
    finally
                { sr.Dispose(); }

            }

            
    public bool IsReusable
            {
                
    get
                {
                    
    return false;
                }
            }
        }

    }
    复制代码

    新建download.ashx

    复制代码
    大气象
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    using System.Net;

    namespace HCLoad.Web
    {
        
    /// <summary>
        
    /// $codebehindclassname$ 的摘要说明
        
    /// </summary>
        public class download : IHttpHandler
        {
            
    private long ChunkSize = 102400;//100K 每次读取文件,只读取100K,这样可以缓解服务器的压力

            
    public void ProcessRequest(HttpContext context)
            {
                
    //string fileName = "123.jpg";//客户端保存的文件名
                String fileName = context.Request.QueryString["filename"]; 
                
    string filePath = context.Server.MapPath("Bubble.jpg");
                System.IO.FileInfo fileInfo 
    = new System.IO.FileInfo(filePath);
                
    if (fileInfo.Exists == true)
                {
                    
    byte[] buffer = new byte[ChunkSize];
                    context.Response.Clear();
                    System.IO.FileStream iStream 
    = System.IO.File.OpenRead(filePath);
                    
    long dataLengthToRead = iStream.Length;//获得下载文件的总大小
                    context.Response.ContentType = "application/octet-stream";
                    
    //通知浏览器下载文件而不是打开
                    context.Response.AddHeader("Content-Disposition""attachment;  filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
                    
    while (dataLengthToRead > 0 && context.Response.IsClientConnected)
                    {
                        
    int lengthRead = iStream.Read(buffer, 0, Convert.ToInt32(ChunkSize));//读取的大小
                        context.Response.OutputStream.Write(buffer, 0, lengthRead);
                        context.Response.Flush();
                        dataLengthToRead 
    = dataLengthToRead - lengthRead;
                    }
                    context.Response.Close();
                    context.Response.End();
                }
                
    //context.Response.ContentType = "text/plain";
                
    //context.Response.Write("Hello World");
            }

            
    public bool IsReusable
            {
                
    get
                {
                    
    return false;
                }
            }
        }
    }
    复制代码

    参考:
    http://www.cnblogs.com/wsdj-ittech/archive/2009/08/26/1554056.html
    http://www.cnblogs.com/wsdj-ittech/archive/2009/08/25/1553534.html
    http://www.cnblogs.com/wmt1708/archive/2009/03/07/1405009.html
    http://topic.csdn.net/u/20090918/10/5e41ab52-f514-46b5-ae6a-d69ddb197213.html
    http://www.cnblogs.com/wsdj-ittech/archive/2009/08/25/1553534.html
    http://www.cnblogs.com/gwazy/archive/2009/04/02/1427781.html
    http://www.cnblogs.com/ewyb/archive/2009/12/10/1621020.html
    http://blog.csdn.net/emily1900/archive/2010/06/08/5655726.aspx

    凡事以大气象去面对,优秀是一种习惯。

     
    分类: SilverLight
    标签: Silverlight
  • 相关阅读:
    Kubernetes源码client-go的workqueue
    (转)Golang语言heap剖析及利用heap实现优先级队列
    (转)Kubernetes GC设计原则
    Kubernetes kubefed使用Cluster Selector
    使用kubeadm添加新节点到集群及相关问题解决
    Kubeadm颁发证书延迟到10年
    kubeadm升级Kubernetes证书
    混合kubebuilder与code generator编写CRD
    (转)Go项目的vendor目录是否需要提交?看这一篇就知道了
    Java 将Excel转为et和ett格式
  • 原文地址:https://www.cnblogs.com/meimao5211/p/3466545.html
Copyright © 2020-2023  润新知