(1)掌握HTTP协议下WCF服务应用程序构建方法。
(2)掌握WCF客户端和服务端的消息交换模式。
(3)掌握协定的设计及实现方法。
(4)熟悉WCF和HTTP的相关绑定设置。
(5)掌握流的读写操作方法。
在同一个解决方案中,分别编写服务端程序和客户端程序,利用HTTP和流传输实现文件下载功能。客户端程序运行效果如图A-4所示。
具体要求
(1)基本功能:文件下载(必做)。
(2)功能扩展:文件上传(选做)。
重点:掌握HTTP协议下WCF服务应用程序构建方法;掌握WCF客户端和服务端的消息交换模式;掌握协定的设计及实现方法;熟悉WCF和HTTP的相关绑定设置。
难点:掌握协定的设计及实现方法;
MainWindow.xaml
Window x:Class="shiyan4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:shiyan4"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Header="请选择可下载的文件">
<ListBox x:Name="lb1"/>
</GroupBox>
<Border Grid.Row="1" Background="Beige" Padding="0 5 0 5">
<Button x:Name="btnDownload" Content="开始下载" Width="100" Height="19" VerticalAlignment="Top" Click="btnDownload_Click"/>
</Border>
<GroupBox Grid.Row="2" Header="下载信息">
<ScrollViewer>
<StackPanel TextBlock.LineHeight="20">
<TextBlock x:Name="tb1" TextWrapping="Wrap" Margin="0 10 0 0"/>
</StackPanel>
</ScrollViewer>
</GroupBox>
</Grid>
</Window>
MainWindow.xaml.cs
using ServiceReference1;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace shiyan4
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
String[] info;
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Service1Client client=new Service1Client();
info = client.getFilesInfo();
foreach (String file in info)
{
String[] s = file.Split(",");
Label label = new Label();
label.Content = String.Format("文件名:{0},文件长度:{1}字节", s[0], s[1]) ;
lb1.Items.Add(label) ;
}
client.Close();
if(lb1.Items.Count > 0)
{
lb1.SelectedIndex = 0;
btnDownload.IsEnabled = true;
}
else
{
btnDownload.IsEnabled = false;
addInfo("找不到可以下载的文件!");
}
}
private void addInfo(String info)
{
tb1.Text += info;
tb1.Text += Environment.NewLine;
}
private void btnDownload_Click(object sender, RoutedEventArgs e)
{
tb1 .Text = "";
String[] a = info[lb1.SelectedIndex].Split(",");
addInfo(String.Format("正在下载{0}", a[0]));
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
Stream stream = client.DownloadStream(a[0]);
String path=System.IO.Path.Combine(Environment.CurrentDirectory, a[0]);
streamToFile(stream, path);
}
private void streamToFile(Stream stream,String path)
{
const int BUFSIZE = 4096;
byte[] buffer = new byte[BUFSIZE];
FileStream fileStream = File.Open(path, FileMode.Create, FileAccess.Write);
int count=0;
int all = 0;
while ((count = stream.Read(buffer, 0, BUFSIZE)) > 0)
{
fileStream.Write(buffer, 0, count);
all += count;
}
stream.Close();
fileStream.Close();
addInfo(String.Format("下载完成,共下载{0}字节,文件保存到{1}", all, path));
}
}
}
IService1.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService1
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
[ServiceContract]
public interface IService1
{
[OperationContract]
List<String> getFilesInfo();
[OperationContract]
Stream DownloadStream(string fileName);
// TODO: 在此添加您的服务操作
}
}
Service1.svc
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService1
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。
// 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。
public class Service1 : IService1
{
public static List<String> filesInfo;
public static String path;
public Stream DownloadStream(string fileName)
{
String filePath=Path.Combine(path, fileName);
FileStream fileStream=File.OpenRead(filePath);
return fileStream;
}
public List<string> getFilesInfo()
{
if (filesInfo == null)
{
filesInfo = new List<String>();
path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DownloadFiles");
DirectoryInfo directoryInfo = new DirectoryInfo(path);
var f = directoryInfo.EnumerateFiles();
foreach ( var f2 in f)
{
//格式:文件名,以字节为单位的文件长度
filesInfo.Add(String.Format("{0},{1}",f2.Name,f2.Length));
}
}
return filesInfo;
}
}
}
Web.config(这里是添加的配置文件)
<bindings>
<basicHttpBinding>
<binding name="b1" transferMode="Buffered" textEncoding="utf-8" messageEncoding="Text">
<security mode="None"/>
</binding>
</basicHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<services>
<service name="WcfService1.Service1">
<endpoint binding="basicHttpBinding" bindingConfiguration="b1" contract="WcfService1.IService1"/>
</service>
</services>
写一下午了,累翻了,想死。