用WebClient将客户端上传文件保存到远端文件服务器

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

要上传文件到服务器也很简单,可以直接使用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服务器,文件服务器和客户端关系:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值