[索引页]
[×××] 


化零为整WCF(8) - 消息处理(使用流数据传输文件)


作者:webabcd


介绍
WCF(Windows Communication Foundation) - 消息处理:使用流数据传输文件,减少内存开销


示例
1、服务
IStreamed.cs
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.Collections.Generic;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.Linq;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.Text;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.ServiceModel;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.IO;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲namespace WCF.ServiceLib.Message
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲{
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// <summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// 消息契约(定义与 SOAP 消息相对应的强类型类)
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// </summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        [MessageContract]
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        public class FileWrapper
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        {
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// <summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// 指定数据成员为 SOAP 消息头
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// </summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                [MessageHeader]
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                public string FilePath;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// <summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// 指定将成员序列化为 SOAP 正文中的元素
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// </summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                [MessageBodyMember]
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                public Stream FileData;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        }
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// <summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// IStreamed接口
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// </summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        [ServiceContract]
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        public interface IStreamed
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        {
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// <summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// 上传文件
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// </summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// <remarks>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// 1、支持数据流传输的绑定有:BasicHttpBinding、NetTcpBinding 和 NetNamedPipeBinding
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// 2、流数据类型必须是可序列化的 Stream 或 MemoryStream
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                // /3、传递时消息体(Message Body)中不能包含其他数据,即参数中只能有一个System.ServiceModel.MessageBodyMember
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// </remarks>

化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// <param name="fileWrapper">WCF.ServiceLib.Message.FileWrapper</param>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                [OperationContract]
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                void UploadFile(FileWrapper fileWrapper);
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        }
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲}
 
Streamed.cs
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.Collections.Generic;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.Linq;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.Text;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.ServiceModel;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.IO;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲namespace WCF.ServiceLib.Message
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲{
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// <summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// IStreamed类
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// </summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        public class Streamed : IStreamed
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        {
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// <summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// 上传文件
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// </summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// <param name="fileWrapper">WCF.ServiceLib.Message.FileWrapper</param>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                public void UploadFile(FileWrapper fileWrapper)
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                {
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        var sourceStream = fileWrapper.FileData;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        var targetStream = new FileStream(fileWrapper.FilePath,
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                FileMode.Create,
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                FileAccess.Write,
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                FileShare.None);
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        var buffer = new byte[4096];
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        var count = 0;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        while ((count = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        {
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                targetStream.Write(buffer, 0, count);
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        }
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        targetStream.Close();
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        sourceStream.Close();
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                }
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        }
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲}
 
2、宿主
Streamed.cs
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using (ServiceHost host = new ServiceHost(typeof(WCF.ServiceLib.Message.Streamed)))
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲{
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        host.Open();
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        Console.WriteLine("服务已启动(WCF.ServiceLib.Message.Streamed)");
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        Console.WriteLine("按<ENTER>停止服务");
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        Console.ReadLine();
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲}
 
 
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <services>
            <!--name - 提供服务的类名-->
            <!--behaviorConfiguration - 指定相关的行为配置-->
            <service name="WCF.ServiceLib.Message.Streamed" behaviorConfiguration="MessageBehavior">
                <!--address - 服务地址-->
                <!--binding - 通信方式-->
                <!--contract - 服务契约-->
                <!--bindingConfiguration - 指定相关的绑定配置-->
                <endpoint address="Message/Streamed" binding="netTcpBinding" contract="WCF.ServiceLib.Message.IStreamed" bindingConfiguration="StreamedBindingConfiguration" />
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:12345/Message/Streamed/"/>
                        <add baseAddress="net.tcp://localhost:54321/"/>
                    </baseAddresses>
                </host>
            </service>
        </services>
        <behaviors>
            <serviceBehaviors>
                <behavior name="MessageBehavior">
                    <!--httpGetEnabled - 使用get方式提供服务-->
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <bindings>
            <netTcpBinding>
                    <!--transferMode - 指示通道是使用流处理模式还是缓冲模式来传输请求和响应消息-->
                    <!--maxReceivedMessageSize - 在采用此绑定配置的通道上可接收的最大消息大小(单位:字节)-->
                    <!--receiveTimeout - 在传输引发异常之前可用于完成读取操作的时间间隔-->
                    <binding name="StreamedBindingConfiguration" transferMode="Streamed" maxReceivedMessageSize="1073741824" receiveTimeout="00:10:00" />
            </netTcpBinding>
        </bindings>
    </system.serviceModel>
</configuration>
 
 
3、客户端
Streamed.cs
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.Collections.Generic;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.Linq;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.Text;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.Windows.Forms;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.ServiceModel;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲using System.IO;
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲namespace Client2.Message
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲{
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// <summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// 演示Message.Streamed的类
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        /// </summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        public class Streamed
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        {
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// <summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// 流数据上传文件
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// </summary>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// <param name="source">源文件地址</param>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                /// <param name="destination">目标路径</param>
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                public void HelloStreamed(string source, string destination)
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                {
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        try
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        {
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                var proxy = new MessageSvc.Streamed.StreamedClient();
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                var sr = new System.IO.FileStream(
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                        source, System.IO.FileMode.Open);
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                proxy.UploadFile(destination + Path.GetFileName(source), sr);
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                sr.Close();
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                proxy.Close();
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                MessageBox.Show("上传成功");
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        }
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        catch (Exception ex)
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        {
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                                MessageBox.Show(ex.ToString());
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                        }
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲                }
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲        }
化零为整WCF(8) - 消息处理(使用流数据传输文件)_休闲}
 
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <client>
            <!--address - 服务地址-->
            <!--binding - 通信方式-->
            <!--contract - 服务契约-->
            <endpoint address="net.tcp://localhost:54321/Message/Streamed" binding="netTcpBinding" contract="MessageSvc.Streamed.IStreamed" bindingConfiguration="StreamedBindingConfiguration" />
        </client>
        <bindings>
            <netTcpBinding>
                    <!--transferMode - 指示通道是使用流处理模式还是缓冲模式来传输请求和响应消息-->
                    <!--sendTimeout - 在传输引发异常之前可用于完成写入操作的时间间隔-->
                    <binding name="StreamedBindingConfiguration" transferMode="Streamed" sendTimeout="00:10:00" />
            </netTcpBinding>
        </bindings>
    </system.serviceModel>
</configuration>
 
运行结果:
上传文件后提示上传成功


OK
[×××]