zoukankan      html  css  js  c++  java
  • Silverlight WCF 上传实现

    上一篇中提高Silverlight实现文件上传的一些思路,说实在的,在写哪篇文章之前并没有亲身试验过,虽说是思路,但是万一有偏差还是有点冒险。

    经过自己测试后,得意证明,Silverlight 利用 WCF实现上传确实是如此的简单方便,逻辑上也非常的顺畅。

    废话不说,看过前一篇文章后对Silverlight 利用 WCF实现上传大概有概念上的理解,下面直接就是代码部分了。

    此代码只是先了文件上传,界面没怎么做就两个按钮,文件名和上传消息通知都直接显示在按钮上,这是为了让代码看上去简单,更容易理解,见谅。

    实现:

    首先,创建一个ASP.NET项目,然后再该项目中创建一个用于启动于Silverlight的WCF服务 ,也就是一个SVC文件以及.CS代码文件。我取名为Upload.svc,代码如下

    using System.ServiceModel;

    using System.ServiceModel.Activation;

    using System.Collections.Generic;

    using System.Text;

     

    namespace WebApp4SL

    {

        [ServiceContract(Namespace = "Zeta")]

        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

        public class UpLoad

        {

            [OperationContract]

            public string Upload(byte[] bytes,string filename)

            {

                System.IO.FileStream fs = new System.IO.FileStream(System.Web.HttpContext.Current.Server.MapPath("UploadFile")+"/"+filename,System.IO.FileMode.Create);

     

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

     

                fs.Flush();

     

                fs.Close();

               

                return "成功!";

            }

     

        }

    }

     

     这里成功与否当然应该加入更多判断,例如文件是否有重名,或者是否是可支持的类型,我的示例中都没有判断,实际项目中都应该加上,还有就是错误处理 TRY。

    服务器端就此完成,当然,你还得在ASP.NET项目下新建一个目录用于存放上传来的文件,我命名为UploadFile

    接下来就是客户端Silverlight的代码了,首先创建一个Silverlight项目,然后引用刚才我们创建的WCF服务。接下来写Page.xaml及其代码,Page.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.Xml;

    using System.IO;

    using System.Text;

     

    namespace SilverlightTest

    {

        public partial class Page : UserControl

        {

     

     

            byte[] bytes;

            string filename;

            public Page()

            {

                InitializeComponent();

               

            }

     

            private void UserControl_Loaded(object sender, RoutedEventArgs e)

            {

            }

     

            private void UserControl_KeyDown(object sender, KeyEventArgs e)

            {

            }

     

            private void openfile_Click(object sender, RoutedEventArgs e)

            {

                OpenFileDialog op = new OpenFileDialog();

               

                if (op.ShowDialog()==true)

                {

                    FileStream fs = op.File.OpenRead();

     

                    bytes = new byte[fs.Length];

     

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

     

                    openfile.Content =op.File.Name;

                    filename = op.File.Name;

                }

            }

     

            private void upload_Click(object sender, RoutedEventArgs e)

            {

                if (bytes != null)

                {

                    WebApp.UpLoadClient uc = new SilverlightTest.WebApp.UpLoadClient();

     

                    uc.UploadCompleted += new EventHandler<SilverlightTest.WebApp.UploadCompletedEventArgs>(uc_UploadCompleted);

     

                    uc.UploadAsync(bytes,filename);

                }

            }

     

            void uc_UploadCompleted(object sender, SilverlightTest.WebApp.UploadCompletedEventArgs e)

            {

                openfile.Content = e.Result;

            }

        }

    }

     

    很简单,可以说是简陋,但是很能说明问题。

    最后就是更简单的Page.xaml文件

    <UserControl x:Class="SilverlightTest.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

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

        Width="400" Height="300" xmlns:SilverlightTest="clr-namespace:SilverlightTest" Loaded="UserControl_Loaded" KeyDown="UserControl_KeyDown">

        

         <StackPanel x:Name="sp">

            <Button x:Name="openfile" Content="浏览" Click="openfile_Click"></Button>

            <Button x:Name="upload" Content="上传" Click="upload_Click"></Button>

        </StackPanel>

      

     

    </UserControl>

    至此,完成了Silverlight的上传功能。可以看到,Silverlight在客户端获取文件流,写到了一个缓冲块,然后直接将缓冲块作为WCF服务方法的参数,请求执行WCF服务的方法,这个缓冲块就被传递到了服务器,并在服务器上的WCF服务后台代码被处理,处理效果就是将这个缓冲块写入到一个文件流保存起来。

    很简单吧,而且很直观,与以往写入到HTTP请求流,再从请求流里操作简单了一些,但是你也许会说,这样的方法并不比ASP.NET里那个上传控件简单多少啊。但是直接用上传控件会遇到的两个问题很让人棘手,第一就是文件的体积问题,上传大体积会消耗很多时间,也占用较大服务器内存,随之而来的就是HTTP超时问题,另一个就是进度问题,HTTP上传是无法显示进度的,当然AJAX的分块可以解决,但是如果我们用SILVERLIGHT,就更简单了,将客户端文件流分块写入到缓冲块,然后再一次次分别去调用WCF的服务方法,保存成分块的小文件,最后,执行一次合并方法,将文件合并后保存,我的这个例里没有实现这个功能,但是改进下很容易,分块后,做进度就不是什么问题了吧,因为有WCF方法的异步回调时间,一切都是那么简单。

    另外,如果在没有使用分块上传的情况下单个上传文件比较大,或者分块上传单块过大,有可能出现 NOTFOUND异常,为什么,那是你的WCF配置限制引起的,可以在 WEBCONFI文件里进行修改。添加类似以下配置代码

    <basicHttpBinding>
    <binding name="LargeBuffer" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" textEncoding="UTF-8" sendTimeout="00:05:10" receiveTimeout="00:05:10" openTimeout="00:05:10" closeTimeout="00:05:10">
    <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
    </binding>
    </basicHttpBinding>

    如果不知道怎么配置,可以在VS2008里右键点解WEB.CONFIG 选择 编辑WCF配置 进入配置界面。

  • 相关阅读:
    02 : python 基础语法,流程控制语句
    10 : mysql 主从复制
    docker Dockerfile 参数讲解
    docker service 创建swarm节点服务
    docker image 删除未使用的镜像
    docker config 创建配置文件
    docker wait 命令使用
    docker update 更新容器信息
    docker top 命令使用
    docker tag 修改镜像的标枪
  • 原文地址:https://www.cnblogs.com/ZetaChow/p/2237352.html
Copyright © 2011-2022 走看看