在WinForm中通过HTTP协议向服务器端上传文件

相信用ASP.NET写一个上传文件的网页,大家都会写,但是有没有人想过通过在WinForm中通过HTTP协议上传文件呢?

有些人说要向服务器端上传文件,用FTP协议不是很简单吗?效率又高,为什么还要使用HTTP协议那么麻烦呢?这里面有几个原因:

(1)FTP服务器的部署相对麻烦,还要设置权限,权限设置不对,还会惹来一系列的安全问题。

(2)如果双方都还有防火墙,又不想开发FTP相关的一些端口时,HTTP就会大派用场,就像WEB Services能穿透防火墙一样。

(3)其他的...,还在想呢...

但是使用HTTP也有他的一些问题,例如不能断点续传,大文件上传很难,速度很慢,所以HTTP协议上传的文件大小不应该太大。

说了这么多,原归正传,一般来说,在Winform里通过HTTP上传文件有几种可选的方法:

(1)前面提到的Web Services,就是一种很好的方法,通过编写一个WebMethod,包含有 byte[] 类型的参数,然后调用Web Services的方法,文件内容就会以Base64编码传到服务器上,然后重新保存即可。

Code

当然,这种通过Base64编码的方法效率比较低,那么可以采用WSE,支持附件,并以2进制形式传送,效率会更高。

(2)除了通过WebService,另外一种更简单的方法就是通过WebClient或者HttpWebRequest来模拟HTTP的POST动作来实现。这时候首先需要编写一个asp.net web form来响应上传,代码如下:

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="UploadFileWeb.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
 
<head>
  
<title>WebForm1</title>
  
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
  
<meta name="CODE_LANGUAGE" Content="C#">
  
<meta name="vs_defaultClientScript" content="JavaScript">
  
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
 
</head>
 
<body>
  
<form id="Form1" method="post" runat="server">
  
</form>
 
</body>
</html>
Code

其实这个页面跟我们平常写的asp.net上传文件代码是一样的,在Web 页的Request对象中包含有Files这个对象,里面就包含了通过POST方式上传的所有文件的信息,这时所需要做的就是调用 Request.Files[i].SaveAs方法。

但是怎么让才能在WinForm里面模拟想Web Form POST 数据呢?System.Net命名空间里面提供了两个非常有用的类,一个是WebClient,另外一个是HttpWebRequest类。如果我们不需要通过代理服务器来上传文件,那么非常简单,只需要简单的调用WebClient.UploadFile方法就能实现上传文件:

Code

是不是觉得很简单呢?确实就这么简单。

但是如果要通过代理服务器上传又怎么办呢?那就需要使用到HttpWebRequest,但是该类没有Upload方法,但是幸运的是我们通过Reflector反编译了WebClient.UploadFile方法后,我们发现其内部也是通过WebRequest来实现的,代码如下:

 

Code

在这段代码里面其实最关键的就是如何模拟POST请求,通过分析代码和监视HTTP,我们可以发现模拟的POST格式如下:
-----------------------8c64f47716481f0  //时间戳

Content-Disposition: form-data; name="file"; filename="a.txt"  //文件名

Content-Type: application/octet-stream

//文件的内容

-----------------------8c64f47716481f0
这时候,我们只需自己编码来模拟这么一组数据就行(我们还可以好好借鉴MS的代码呢),以下就是代码(声明一下,我是借用了别人的代码)

Code

在wwHttp这个类里面,不仅仅可以传送文件AddPostFile方法,还可以传送变量AddPostKey方法。

这样,如果我们要通过代理服务器传送文件,就可以编写如下的代码了:

Code
小结:

(1)通过Web Services传文件。

(2)如果不需要使用代理,使用WebClient类

(3)如果需要使用代理,使用扩展得到的类wwHttp

原文地址:https://www.cnblogs.com/wudingfeng/p/1286557.html