博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用WCF实现上传下载文件服务
阅读量:5749 次
发布时间:2019-06-18

本文共 7332 字,大约阅读时间需要 24 分钟。

  hot3.png

本文是转载的,我根据本文的教程,成功写出来一个使用WCF上传和下载文件的程序,现在把原文和我自己写的项目全部上传过来

原文链接:

这是我写的例子的链接:

引言

    前段时间,用WCF做了一个小项目,其中涉及到文件的上传下载。出于复习巩固的目的,今天简单梳理了一下,整理出来,下面展示如何一步步实现一个上传下载的WCF服务。

服务端

      1.首先新建一个名为FileService的WCF服务库项目,如下图:

       技术分享

      2.将Service,IService重命名为FileService,IFileService,如下图:

        技术分享

      3.打开IFileService.cs,定义两个方法,如下:

技术分享
[ServiceContract]    public interface IFileService    {        //上传文件        [OperationContract]        bool UpLoadFile(Stream filestream);        //下载文件        [OperationContract]        Stream DownLoadFile(string downfile);       }
View Code

     4.上面方法定义了输入参数和返回参数,但是实际项目中往往是不够的,我们需要增加其他参数,如文件名,文件大小之类。然而WCF中有限定,如下:

  • 保留要进行流处理的数据的参数必须是方法中的唯一参数。 例如,如果要对输入消息进行流处理,则该操作必须正好具有一个输入参数。 同样,如果要对输出消息进行流处理,则该操作必须正好具有一个输出参数或一个返回值。

  • 参数和返回值的类型中至少有一个必须是 ,  或 。

     所以我们需要用契约特性包装一下参数,修改代码如下:

技术分享
[ServiceContract]    public interface IFileService    {        //上传文件        [OperationContract]        UpFileResult UpLoadFile(UpFile filestream);        //下载文件        [OperationContract]        DownFileResult DownLoadFile(DownFile downfile);    }    [MessageContract]    public class DownFile    {        [MessageHeader]        public string FileName { get; set; }    }    [MessageContract]    public class UpFileResult    {        [MessageHeader]        public bool IsSuccess { get; set; }        [MessageHeader]        public string Message { get; set; }    }    [MessageContract]    public class UpFile    {        [MessageHeader]        public long FileSize { get; set; }        [MessageHeader]        public string FileName { get; set; }        [MessageBodyMember]        public Stream FileStream { get; set; }    }    [MessageContract]    public class DownFileResult    {        [MessageHeader]        public    FileSize { get; set; }        [MessageHeader]        public bool IsSuccess { get; set; }        [MessageHeader]        public string Message { get; set; }        [MessageBodyMember]        public Stream FileStream { get; set; }    }
View Code

    5.现在服务契约定义好了,接下来实现契约的接口。打开FileService.cs文件,编写代码,实现服务端的上传下载文件服务,代码如下:

技术分享
public class FileService : IFileService    {        public UpFileResult UpLoadFile(UpFile filedata)        {            UpFileResult result = new UpFileResult();            string path = System.AppDomain.CurrentDomain.BaseDirectory +@"\service\";            if (!Directory.Exists(path))            {                Directory.CreateDirectory(path);            }            byte[] buffer = new byte[filedata.FileSize];            FileStream fs = new FileStream(path + file.FileName, FileMode.Create, FileAccess.Write);            int count = 0;            while ((count = file.FileStream.Read(buffer, 0, buffer.Length)) > 0)            {                fs.Write(buffer, 0, count);            }            //清空            fs.Flush();            //关闭流            fs.Close();            result.IsSuccess = true;            return result;                  }        //下载文件        public DownFileResult DownLoadFile(DownFile filedata)        {            DownFileResult result = new DownFileResult();            string path = System.AppDomain.CurrentDomain.BaseDirectory + @"\service\" + file.FileName;            if (!File.Exists(path))            {                result.IsSuccess = false;                result.FileSize = 0;                result.Message = "服务器不存在此文件";                result.FileStream = new MemoryStream();                return result;            }            Stream ms = new MemoryStream();               FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);            fs.CopyTo(ms);            ms.Position = 0;  //重要,不为0的话,客户端读取有问题            result.IsSuccess = true;            result.FileSize = ms.Length;            result.FileStream = ms;            fs.Flush();            fs.Close();            return result;        }    }
View Code

    6.至此,具体实现代码完成,但是我们还需要配置一下App.config,设置地址,契约和绑定。这里绑定采用NetTcpBinding,我们还需要为NetTcpBinding具体配置,如maxReceivedMessageSize(配置最大接收文件大小),transferMode(传输模式,这里是Streamed)等。最终代码如下:

技术分享
< key=":UseTaskFriendlySynchronizationContext" value="true" />
< baseAddress="net.tcp://localhost:8734/Design_Time_Addresses/WcfTest/Service1/" />
View Code

    7.这时可以运行服务,如果没有问题的话,会看到如下截图。

   技术分享

客户端

  1.首先新建一个WPF应用程序,在MainWindow.xaml添加控件,得到下图:

      技术分享

     2.在引用中右击,选择添加服务引用,出现对话框,我们需要填上刚才打开的服务的地址,然后按旁边的转到,会看到显示找到服务,接着更改命名空间为FileService,得到如下图。

     技术分享

    2.按确定之后,在资源管理器里的引用下面会多出一个FileService命名空间,里面包含我们的刚才写的FileServiceClient服务代理类 ,现在我们可以通过它调用服务了。编写代码如下:

技术分享
public partial class MainWindow : Window    {        FileServiceClient client;        public MainWindow()        {            InitializeComponent();            client = new FileServiceClient();        }        private void Button_Click_1(object sender, RoutedEventArgs e)        {            OpenFileDialog Fdialog = new OpenFileDialog();            if (Fdialog.ShowDialog().Value)            {                using (Stream fs = new FileStream(Fdialog.FileName, FileMode.Open, FileAccess.Read))                {                    string message;                    this.filepath.Text = Fdialog.SafeFileName;                    bool result = client.UpLoadFile(Fdialog.SafeFileName, fs.Length,fs, out message);                    if (result == true)                    {                        MessageBox.Show("上传成功!");                    }                    else                    {                        MessageBox.Show(message);                    }                }            }        }        private void Button_Click_2(object sender, RoutedEventArgs e)        {            string filename = this.filename.Text;            string path = System.AppDomain.CurrentDomain.BaseDirectory + @"\client\";            bool issuccess=false;            string message="";            Stream filestream=new MemoryStream();             filesize = client.DownLoadFile(filename, out issuccess, out message, out filestream);            if (issuccess)            {                if (!Directory.Exists(path))                {                    Directory.CreateDirectory(path);                }                byte[] buffer = new byte[filesize];                FileStream fs = new FileStream(path + filename, FileMode.Create, FileAccess.Write);                int count = 0;                while ((count = filestream.Read(buffer, 0, buffer.Length)) > 0)                {                    fs.Write(buffer, 0, count);                }                //清空                fs.Flush();                //关闭流                fs.Close();                MessageBox.Show("下载成功!");            }            else            {                MessageBox.Show(message);                        }        }    }
View Code

 

   3.运行程序,上传下载文件,会在和客服端运行目录下分别找到上传的文件和下载的文件,测试通过。界面如下:

   技术分享技术分享

小结

  本文通过图文一步步介绍了如何实现上传下载文件功能,其中涉及到WCF知识点其实是不少的,但是都是简单地带过。如果有不明白的地方,可以查阅Google,百度,也可以留言。如果您有更好的建议,请不吝指教,感激不尽!

转载于:https://my.oschina.net/dongri/blog/610908

你可能感兴趣的文章
基于 Android NDK 的学习之旅----- C调用Java
查看>>
开始第一个Python程序!
查看>>
Google 或强制 OEM 预装 20 款应用,给你一个不Root的理由
查看>>
我的友情链接
查看>>
双边过滤器(Bilateral filter)
查看>>
Android图形显示系统——下层显示4:图层合成上(合成原理与3D合成)
查看>>
Windows 10 技术预览
查看>>
Tomcat http跳转https
查看>>
一个自动布署.net网站的bat批处理实例
查看>>
tomcat 安装
查看>>
AIX:物理卷及有关概念
查看>>
Install and Configure OpenStack Object Storage (Swift) for Ubuntu 14.04
查看>>
我的友情链接
查看>>
Centos6.6安装选包及基础场景说明
查看>>
《从零开始学Swift》学习笔记(Day 61)——Core Foundation框架之内存管理
查看>>
java基础面试题-1
查看>>
深克隆与序列化效率的比较
查看>>
C++入门篇01
查看>>
3.python开发语言的特点
查看>>
Nginx使用Proxy_cache实现服务器端静态文件缓存
查看>>