WCF流与文件传输、数据契约和消息契约

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Runtime.Serialization;
using System.Reflection;
using System.IO;

namespace WcfDemo1
{
    ///   
    /// 实现服务协定接口的服务类  
    ///   
    class Program
    {
        /// 
        /// 服务器端
        /// 
        /// 
        static void Main(string[] args)
        {
            // 服务器基址  
            Uri baseAddress = new Uri("http://localhost:1378/services");
            // 声明服务器主机  
            using (ServiceHost host = new ServiceHost(typeof(MyService), baseAddress))
            {
                // 添加绑定和终结点  
                BasicHttpBinding binding = new BasicHttpBinding();
                // 启用流模式  
                binding.TransferMode = TransferMode.StreamedRequest;
                binding.MaxBufferSize = 1024;
                // 接收消息的最大范围为500M  
                binding.MaxReceivedMessageSize = 500 * 1024 * 1024;
                host.AddServiceEndpoint(typeof(IService), binding, "/test");
                // 添加服务描述  
                host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
                try
                {
                    // 打开服务  
                    host.Open();
                    Console.WriteLine("服务已启动。");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                Console.ReadKey();
            }
            /* 备注
             * 利用数据契约已经能够很好地完成数据的传输了,而数据契约只能控制消息体,
             * 有时候我们想在数据传递过程中添加一些额外信息,而不希望添加额外的契约字段,
             * 那么我们就得改消息报头,也就是说该使用消息契约了
             * 消息契约第一个典型应用就是在执行文件传输时,文件的二进制信息放到body里,
             * 而一些复加的文件信息则放在head里
             */
        }

    }

    [ServiceContract(Namespace = "MyNamespace")]
    public interface IService
    {
        [OperationContract]
        ResultMessage UpLoadFile(TransferFileMessage tMsg);
    }

    public class MyService : IService
    {
        public ResultMessage UpLoadFile(TransferFileMessage tMsg)
        {
            ResultMessage rMsg = new ResultMessage();
            if (tMsg == null || tMsg.File_Stream == null)
            {
                rMsg.ErrorMessage = "传入的参数无效。";
                rMsg.IsSuccessed = false;
                return rMsg;
            }
            try
            {
                using (FileStream outputStream = new FileStream(tMsg.File_Name, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    // 我们不用对两个流对象进行读写,只要复制流就OK  
                    tMsg.File_Stream.CopyTo(outputStream);
                    outputStream.Flush();
                    rMsg.IsSuccessed = true;
                    Console.WriteLine("在{0}接收到客户端发送的流,已保存到{1}。", DateTime.Now.ToLongTimeString(), tMsg.File_Name);
                }
            }
            catch (Exception ex)
            {
                rMsg.IsSuccessed = false;
                rMsg.ErrorMessage = ex.Message;
            }
            return rMsg;
        }  
    }

    [MessageContract]
    public class TransferFileMessage
    {
        [MessageHeader]
        public string File_Name; //文件名  
        [MessageBodyMember]
        public Stream File_Stream; //文件流  
    }

    [MessageContract]
    public class ResultMessage
    {
        [MessageHeader]
        public string ErrorMessage;
        [MessageBodyMember]
        public bool IsSuccessed;
    }  
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Client
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnSelectFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "MP3音频文件|*.mp3";
            if (DialogResult.OK.Equals(dlg.ShowDialog()))
            {
                this.lbSelectedFilename.Text = dlg.FileName;
                this.lbMessage.Text = "准备就绪。";
            }  
        }

        private async void btnTransfer_Click(object sender, EventArgs e)
        {
            //异步上传
            if (!File.Exists(this.lbSelectedFilename.Text))
            {
                return;
            }
            FileStream fs = new FileStream(this.lbSelectedFilename.Text, FileMode.Open, FileAccess.Read);
            WS.ServiceClient cl = new WS.ServiceClient();
            this.btnTransfer.Enabled = false;
            var response = await cl.UpLoadFileAsync(Path.GetFileName(this.lbSelectedFilename.Text), fs);
            this.btnTransfer.Enabled = true;
            if (response.IsSuccessed == true)
                this.lbMessage.Text = "上传完成。";
            else
                this.lbMessage.Text = "错误信息:" + response.ErrorMessage;   
        }
    }
}

WCF流与文件传输、数据契约和消息契约_第1张图片

WCF流与文件传输、数据契约和消息契约_第2张图片

你可能感兴趣的:(WCF)