我们知道,在实现WCF传送二进制流数据这一操作过程中,会有一些限制因素。我们在实际应用中要特别注意这一点。今天我们就会针对这方面的问题做一个详细的介绍,希望对大家有所帮助。#t#

创新互联是一家专注于成都网站制作、网站建设与策划设计,卢龙网站建设哪家好?创新互联做网站,专注于网站建设十载,网设计领域的专业建站公司;建站业务涵盖:卢龙等地区。卢龙做网站价格咨询:18980820575
只有 BasicHttpBinding、WebHttpBinding、NetTcpBinding 和 NetNamedPipeBinding 支持传送流数据。 
 流数据类型必须是可序列化的 Stream 或 MemoryStream。 
 传递时消息体(Message Body)中不能包含其他数据。
我们先看看下面的WCF传送二进制流数据例子。
注意将 Binding.TransferMode 设置为 TransferMode.Streamed,我们还可以修改 Binding.MaxReceivedMessageSize 来调整消息大小(默认是64KB)。
- [ServiceContract]
 - public interface IFileService
 - {
 - [OperationContract]
 - void Upload(Stream stream);
 - }
 - public class FileService : IFileService, IDisposable
 - {
 - public void Upload(Stream stream)
 - {
 - FileStream file = new FileStream("test.dll", FileMode.Create);
 - try
 - {
 - BinaryWriter writer = new BinaryWriter(file);
 - BinaryReader reader = new BinaryReader(stream);
 - byte[] buffer;
 - do
 - {
 - buffer = reader.ReadBytes(1024);
 - writer.Write(buffer);
 - }
 - while (buffer.Length > 0);
 - }
 - finally
 - {
 - file.Close();
 - stream.Close();
 - }
 - }
 - public void Dispose()
 - {
 - Console.WriteLine("Dispose...");
 - }
 - }
 - public class WcfTest
 - {
 - public static void Test()
 - {
 - AppDomain.CreateDomain("Server").DoCallBack(delegate
 - {
 - ServiceHost host = new ServiceHost(typeof(FileService),
 - new Uri("http://localhost:8080/FileService"));
 - BasicHttpBinding binding = new BasicHttpBinding();
 - binding.TransferMode = TransferMode.Streamed;
 - host.AddServiceEndpoint(typeof(IFileService), binding, "");
 - host.Open();
 - });
 - BasicHttpBinding binding2 = new BasicHttpBinding();
 - binding2.TransferMode = TransferMode.Streamed;
 - IFileService channel = ChannelFactory
 . 
CreateChannel(binding2,- new EndpointAddress("http://localhost:8080/FileService"));
 - using (channel as IDisposable)
 - {
 - FileStream stream = new FileStream("MyLibrary2.dll", FileMode.Open);
 - channel.Test(stream);
 - stream.Close();
 - }
 - }
 - }
 
一切正常。那么 "传递时消息体(Memory Body)中不能包含其他数据" 是什么意思?我们修改一下上面的契约,除了传递文件流外,我们还希望传递文件名。
- [ServiceContract]
 - public interface IFileService
 - {
 - [OperationContract]
 - void Upload(string filename, Stream stream);
 - }
 - // ... 其他代码暂略 ...
 
当你修改完WCF传送二进制流数据的代码后,运行时你发现触发了一个 InvalidOperationException 异常。
未处理 System.InvalidOperationException
 Message="For request in operation Upload to be a stream the operation must have a single parameter whose type is Stream."
 Source="System.ServiceModel"
那么该怎么办呢?DataContract 肯定不行。 没错!你应该记得 MessageContract,将 filename 放到 MessageHeader 里面就行了。
- [MessageContract]
 - public class FileData
 - {
 - [MessageHeader]public string filename;
 - [MessageBodyMember]public Stream data;
 - }
 - [ServiceContract]
 - public interface IFileService
 - {
 - [OperationContract]
 - void Upload(FileData file);
 - }
 - public class FileService : IFileService, IDisposable
 - {
 - public void Upload(FileData file)
 - {
 - FileStream f = new FileStream(file.filename, FileMode.Create);
 - try
 - {
 - BinaryWriter writer = new BinaryWriter(f);
 - BinaryReader reader = new BinaryReader(file.data);
 - byte[] buffer;
 - do
 - {
 - buffer = reader.ReadBytes(1024);
 - writer.Write(buffer);
 - }
 - while (buffer.Length > 0);
 - }
 - finally
 - {
 - f.Close();
 - file.data.Close();
 - }
 - }
 - public void Dispose(){
 - Console.WriteLine("Dispose...");
 - }
 - }
 - public class WcfTest
 - {
 - public static void Test()
 - {
 - AppDomain.CreateDomain("Server").DoCallBack(delegate
 - {
 - ServiceHost host = new ServiceHost(typeof(FileService),
 - new Uri("http://localhost:8080/FileService"));
 - BasicHttpBinding binding = new BasicHttpBinding();
 - binding.TransferMode = TransferMode.Streamed;
 - host.AddServiceEndpoint(typeof(IFileService), binding, "");
 - host.Open();
 - });
 - BasicHttpBinding binding2 = new BasicHttpBinding();
 - binding2.TransferMode = TransferMode.Streamed;
 - IFileService channel = ChannelFactory
 . 
CreateChannel(binding2,- new EndpointAddress("http://localhost:8080/FileService"));
 - using (channel as IDisposable)
 - {
 - FileData file = new FileData();
 - file.filename = "test2.dll";
 - file.data = new FileStream("MyLibrary2.dll", FileMode.Open);
 - channel.Upload(file);
 - file.data.Close();
 - }
 - }
 - }
 
问题解决了。上面的例子使用 BaseHttpBinding,如果使用 NetTcpBinding,相信速度要快很多。除了向服务器传送流外,也可反向返回流数据。
- [ServiceContract]
 - public interface IFileService
 - {
 - [OperationContract]
 - void Upload(Stream stream);
 - [OperationContract]
 - Stream Download(string filename);
 - }
 
虽然服务器在操作结束时会自动关闭客户端 Request Stream,但个人建议还是使用 try...finnaly... 自主关闭要好一些,因为意外总是会发生的。
WCF传送二进制流数据的全部操作方法就为大家介绍到这里。
                当前文章:WCF传送二进制流数据基本实现步骤详解
                
                网站路径:http://www.csdahua.cn/qtweb/news19/527869.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网