WCF的实现(方式二)

参考他人实现文件传输

【WCF】利用WCF实现上传下载文件服务

服务端:

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

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

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

 1 [ServiceContract]
 2     public interface IFileService
 3     {
 4 
 5         //上传文件
 6         [OperationContract]
 7         bool UpLoadFile(Stream filestream);
 8 
 9         //下载文件
10         [OperationContract]
11         Stream DownLoadFile(string downfile); 
12   
13     }

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

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

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

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

 1 [ServiceContract]
 2     public interface IFileService
 3     {
 4         //上传文件
 5         [OperationContract]
 6         UpFileResult UpLoadFile(UpFile filestream);
 7 
 8         //下载文件
 9         [OperationContract]
10         DownFileResult DownLoadFile(DownFile downfile);
11     }
12 
13     [MessageContract]
14     public class DownFile
15     {
16         [MessageHeader]
17         public string FileName { get; set; }
18     }
19 
20     [MessageContract]
21     public class UpFileResult
22     {
23         [MessageHeader]
24         public bool IsSuccess { get; set; }
25         [MessageHeader]
26         public string Message { get; set; }
27     }
28 
29     [MessageContract]
30     public class UpFile
31     {
32         [MessageHeader]
33         public long FileSize { get; set; }
34         [MessageHeader]
35         public string FileName { get; set; }
36         [MessageBodyMember]
37         public Stream FileStream { get; set; }
38     }
39 
40     [MessageContract]
41     public class DownFileResult
42     {
43         [MessageHeader]
44         public long   FileSize { get; set; }
45         [MessageHeader]
46         public bool IsSuccess { get; set; }
47         [MessageHeader]
48         public string Message { get; set; }
49         [MessageBodyMember]
50         public Stream FileStream { get; set; }
51     }

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

 1 public class FileService : IFileService
 2     {
 3         public UpFileResult UpLoadFile(UpFile filedata)
 4         {
 5 
 6             UpFileResult result = new UpFileResult();
 7 
 8             string path = System.AppDomain.CurrentDomain.BaseDirectory +@"\service\";
 9 
10             if (!Directory.Exists(path))
11             {
12                 Directory.CreateDirectory(path);
13             }
14 
15             byte[] buffer = new byte[filedata.FileSize];
16 
17             FileStream fs = new FileStream(path + filedata.FileName, FileMode.Create, FileAccess.Write);
18 
19             int count = 0;
20             while ((count = filedata.FileStream.Read(buffer, 0, buffer.Length)) > 0)
21             {
22                 fs.Write(buffer, 0, count);
23             }
24             //清空缓冲区
25             fs.Flush();
26             //关闭流
27             fs.Close();
28 
29             result.IsSuccess = true;
30 
31             return result;
32           
33         }
34 
35         //下载文件
36         public DownFileResult DownLoadFile(DownFile filedata)
37         {
38 
39             DownFileResult result = new DownFileResult();
40 
41             string path = System.AppDomain.CurrentDomain.BaseDirectory + @"\service\" + filedata.FileName;
42 
43             if (!File.Exists(path))
44             {
45                 result.IsSuccess = false;
46                 result.FileSize = 0;
47                 result.Message = "服务器不存在此文件";
48                 result.FileStream = new MemoryStream();
49                 return result;
50             }
51             Stream ms = new MemoryStream();   
52             FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
53             fs.CopyTo(ms);
54             ms.Position = 0;  //重要,不为0的话,客户端读取有问题
55             result.IsSuccess = true;
56             result.FileSize = ms.Length;
57             result.FileStream = ms;
58 
59             fs.Flush();
60             fs.Close();
61             return result;
62         }
63     }

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

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3 
 4   <appSettings>
 5     <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
 6   </appSettings>
 7   <system.web>
 8     <compilation debug="true" />
 9   </system.web>
10   <!-- 部署服务库项目时,必须将配置文件的内容添加到 
11   主机的 app.config 文件中。System.Configuration 不支持库的配置文件。-->
12   <system.serviceModel>
13     
14     <bindings>
15        <netTcpBinding>
16         <binding name="MyTcpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" sendTimeout="00:30:00" transferMode="Streamed"   >
17           <security mode="None"></security>
18         </binding> 
19       </netTcpBinding>
20     </bindings>
21           
22     <services>
23       <service name="WcfTest.FileService">
24         <endpoint address="" binding="netTcpBinding" bindingConfiguration="MyTcpBinding" contract="WcfTest.IFileService">
25           <identity>
26             <dns value="localhost" />
27           </identity>
28         </endpoint>
29         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
30         <host>
31           <baseAddresses>
32              <add baseAddress="http://localhost:8733/Design_Time_Addresses/WcfTest/Service1/" />
33             <add baseAddress="net.tcp://localhost:8734/Design_Time_Addresses/WcfTest/Service1/" />
34           </baseAddresses>
35         </host>
36       </service>
37     </services>
38     <behaviors>
39       <serviceBehaviors>
40         <behavior>
41           <!-- 为避免泄漏元数据信息,
42           请在部署前将以下值设置为 false -->
43           <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
44           <!-- 要接收故障异常详细信息以进行调试,
45           请将以下值设置为 true。在部署前设置为 false 
46             以避免泄漏异常信息-->
47           <serviceDebug includeExceptionDetailInFaults="False" />
48         </behavior>
49       </serviceBehaviors>
50     </behaviors>
51   </system.serviceModel>
52 
53 </configuration>

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

 第七步出问题了:

直接复制App.config的内容,并点击运行,会以下出错(哈哈,肯定的呀)

 右键App.config,选择“编辑WCF配置”,

 

参考:

感谢!

【WCF】利用WCF实现上传下载文件服务

https://www.cnblogs.com/caizl/p/4326016.html

https://www.cnblogs.com/wolf-sun/p/3277599.html

猜你喜欢

转载自www.cnblogs.com/upcsyt/p/12510561.html
WCF