要上传文件到服务器也很简单,可以直接使用Form提交一个enctype = 'multipart/form-data'的表单,再从服务器接收一下就可以了。但如果想将文件传到另一台文件服务器又可以怎样呢。可以从服务器触发一些计划任务,将文件复制过去,也可以使用如BT的方式,同步到多个服务器。其实我还是更喜欢使用后者,这样工作量少很多,特别要同步到多个服务器做负载均衡时。
不过今天要介绍不是上述的方式,是使用WebClient将文件直接PUT到一部文件服务器。直接上代码(.net3.5):
private void SaveToWebServer(HttpPostedFile hpf)
{
WebClient webClient = new WebClient();
ICredentials c = new NetworkCredential("computer\\user","123123");
try
{
webClient.Credentials = c;
byte[] tmpBytes = new byte[hpf.InputStream.Length];
hpf.InputStream.Read(tmpBytes, 0, tmpBytes.Length);
string fileNameOnly = GetFileName(hpf.FileName);
webClient.UploadData(new Uri("http://192.168.1.111:90/UploadFiles/" + fileNameOnly), "PUT", tmpBytes);
}
catch (Exception)
{
throw;
}
}
private void SaveToWebServer(System.IO.Stream stream)
{
WebClient webClient = new WebClient();
ICredentials c = new NetworkCredential("computer\\user", "123123");
try
{
webClient.Credentials = c;
byte[] tmpBytes = new byte[stream.Length];
stream.Read(tmpBytes, 0, tmpBytes.Length);
string fileNameOnly = GetFileName(Request["up1"]);
webClient.UploadData(new Uri("http://192.168.1.111:90/UploadFiles/" + fileNameOnly), "PUT", tmpBytes);
}
catch (Exception ex)
{
throw;
}
}
上面代码就是创建一个WebClient,设置验证授权,从HttpPostedFile读出上传文件的字节,然后使用WebClient.UploadData( Uri, "Method", byte[] ) 上传到服务器。
Uri中要给定具体的目标路径和文件名。
注意:此时由于文件服务器没相应的处理程序,因此,IIS的网站要打开写权限,和添加相应的用户名。
路径只能是服务器上的虚拟路径,不是目标机器的物理路径。因为访问方式是 http:/www.domain.com/upload/file1.txt 这样的URL。WebClient中还有很多其它上传的方法,如 UploadFile,OpenWrite两个方法可用于上传文件。
UploadFile 是将本地文件上传到服务器,但先要将文件保存到网站所在的Web服务器,再传到目标的文件服务器。
OpenWrite 是打开一个Stream,可将接将浏览器传过来的文件输入流传到目标文件服务器上。
.net 3.5的参考: http://technet.microsoft.com/zh-cn/library/system.net.webclient(v=vs.90).aspx
4.0的内容也一样,但增加一些支持异步和TaskAsync的方法。
既然服务器代码有了,文件服务器的设置也有了,那如何从客户端Post一个文件呢。下面介绍几种方法( WebForm,Form,Ajax)。
表单(不解释):
<body>
<form id="form1" runat="server">
<div>
普通Upload【WebForm】<br />
<asp:FileUpload ID="file1" runat="server" style="width:300px;" />
<br />
<asp:Button ID="btnSubmit1" runat="server" Text = " 保 存 文 件 " />
</div>
</form>
<div>
普通Http Form Tag Upload
<form id="form2" name="form2" action="upload/UploadFileHandler.ashx" method="post" enctype="multipart/form-data">
<input type="file" name="up1" id="up1" style="width:300px;" />
<br />
<input type="submit" id="submit1" name="submit" value=" 保 存 文 件 " />
</form>
</div>
<div>
AjaxForm upload
<form id="form3" name = "form3" action="upload/UploadFileHandler.ashx" method="post" enctype="multipart/form-data">
<input type="file" id="Up2" name="Up2" style="width:300px;" />
<br/>
<input type="button" name="btnUpload" id="btnUpload" value = " 保 存 文 件 " onclick="uploadFileToServer()"/>
<iframe src="about:blank;" id="ajaxFrame" style="width:0px;height:0px;left:-1000px;position:absolute;" name="ajaxFrame"></iframe>
</form>
</div>
</body>
浏览器上看:
AJAX使用的脚本:
function uploadFileToServer() {
var xhr = new XMLHttpRequest();
var f3 = document.getElementById("form3");
if (typeof FormData != "undefined") {
var fd = new FormData(f3);
xhr.open("POST", form3.action, true);
xhr.onreadystatechange = function() {
if (xhr.status == "200" && xhr.readyState == "4") {
var d = xhr.responseText;
var jsonD = eval("(" + d + ")");
if (jsonD.success) {
alert("Upload OK");
}
}
};
xhr.send(fd);
}
else {
f3.target = "ajaxFrame";
var ajaxF = document.getElementById("ajaxFrame");
ajaxF.setAttribute("onload", "showmsg()");
f3.submit();
}
}
function showmsg() {
var f = document.getElementById("ajaxFrame");
var d = "";
if (f.contentDocument) {
d = f.contentDocument.body.innerHTML;
} else {
d = f.contentWindow.document.body.innerHTML;
}
var j = d!=""?eval("(" + d + ")"):new Object();
if (j != undefined) {
if (j["success"] != undefined && j.success) {
alert("Upload OK");
}
}
f.setAttribute("onload", "");
f.src = "about:blank;";
}
脚本中的FormData 是XMLHttpRequest Level2 中使用的,IE9+,Chrome,Opera10+,其它未测试过。
var f = new FormData(form); 就是用Form表单来构造一个FormData对象,xhr.send() 时将整个FormData对象作为参数,传给服务器。
Web服务器接收上传数据(敷衍General HttpHandler .ashx)
如果是WebForm,则使用:
HttpFileCollection hfc = Request.Files;
获取上传的文件列表即可。
如果用的是普通 的Form,即 <form action = "" method ="" enctype="multipart/form-data"> 这样提交的,使用
Request.InputStream;来获取上传流,可以自己分割多个文件。如果预知页面的file控件的name属性,也可以Request到。
Request["file1"];
最后就使用开头的方法,将流使用WebClient发送到远端的文件服务器。如果需要同步到其它分流服务器,就各显神通吧。
如果有域名及负载均衡的环境,就有需要将文件放到一个独立的静态资源服务器中进行共享,不可以将文件单独存放在网页服务器的本地。
附上Web服务器,文件服务器和客户端关系:

本文介绍了如何使用WebClient类将文件直接PUT到远程文件服务器,适用于需要将文件从客户端跨服务器上传的情况。通过提供C#代码示例,展示了UploadFile和OpenWrite方法的用法,并提及了客户端使用表单、AJAX进行文件上传的处理方式。此外,还讨论了在有负载均衡环境下的静态资源服务器的重要性。

454

被折叠的 条评论
为什么被折叠?



