Flex與.NET互操作 使用FileReference+HttpHandler實(shí)現(xiàn)文件上傳/下載
在Flex的應(yīng)用開(kāi)發(fā)中,同ASP.NET,JSP,PHP等應(yīng)用一樣,都會(huì)有上傳/下載文件的應(yīng)用需求,F(xiàn)lex的SDK也為我們提供了專(zhuān)門(mén)的類(lèi) FileRefUdderence實(shí)現(xiàn)文件上傳/下載。Flex只是作為一個(gè)客戶端,要實(shí)現(xiàn)上傳或下載必須得為其提供一個(gè)服務(wù)端來(lái)接受上傳或下載的請(qǐng)求,本文以ASP.NET中的HttpHandler作為文件上傳的服務(wù)端來(lái)完成上傳功能。
OK,我們從Flex客戶端開(kāi)始,看看客戶端是通過(guò)什么方式想服務(wù)端發(fā)起請(qǐng)求。Flex客戶端要完成文件上傳下載都是通過(guò)FileRefUdderence來(lái)實(shí)現(xiàn),首先得定義一個(gè)該類(lèi)型對(duì)象實(shí)例:
2 private var stateText:String = "請(qǐng)選擇一個(gè)文件上傳";
3 //通過(guò)調(diào)用file對(duì)象的方法來(lái)完成上傳和下載功能
4 private var file:FileReference = new FileReference();
上傳文件通常涉及到的有選擇文件、上傳文件以及上傳完成這些最基本的處理過(guò)程。OK,下面我們就以這三個(gè)過(guò)程為例來(lái)看看Flex是怎么來(lái)完成文件的上傳功能。首先為這三個(gè)功能點(diǎn)分別添加監(jiān)聽(tīng)事件處理函數(shù),在程序加載時(shí)調(diào)用:
2 {
3 file.addEventListener(Event.SELECT,onSelected);
4 file.addEventListener(Event.COMPLETE,onCompleted);
5 file.addEventListener(ProgressEvent.PROGRESS,onProgress);
6 }
另外我們也可以不用上面這中定義一個(gè)函數(shù)在程序加載時(shí)調(diào)用進(jìn)行初始化操作,應(yīng)用程序(mxml)的初始化操作又 creationComplete方法完成,另外還有一個(gè)比它先執(zhí)行的方法createChildren(),我們可以直接在mxml下重寫(xiě)該方法來(lái)實(shí)現(xiàn)應(yīng)用程序的初始化,如下:
2 * createChildren 比 creationComplete 事件更早發(fā)生
3 * */
4 protected override function createChildren():void
5 {
6 file.addEventListener(Event.SELECT,onSelected);
7 file.addEventListener(Event.COMPLETE,onCompleted);
8 file.addEventListener(ProgressEvent.PROGRESS,onProgress);
9 }
這三個(gè)事件處理函數(shù)的詳細(xì)定義如下(其中的stateText為String的變量,用于顯示文件上傳狀態(tài)提示):
2 {
3 stateText = "選擇了文件" + file.name;
4 }
5
6 internal function onCompleted(evt:Event):void
7 {
8 stateText = "上傳完畢!";
9 }
10
11 internal function onProgress(evt:ProgressEvent):void
12 {
13 stateText = "已上傳 " + Math.round(100 * evt.bytesLoaded / evt.bytesTotal) + "%";
14 }
到這里客戶端就只差一步了,那就是完成發(fā)起上傳請(qǐng)求的方法,實(shí)際上就是通過(guò)URLRequest對(duì)象創(chuàng)建一個(gè)與服務(wù)端的連接,然后直接調(diào)用FielReference類(lèi)的upload()方法就可完成該功能,詳細(xì)如下代碼定義:
2 * 調(diào)用FileReference的實(shí)例方法upload()實(shí)現(xiàn)文件上傳
3 * */
4 internal function onUpLoad():void
5 {
6 if(file.size > 0)
7 {
8 stateText = "正在上傳文件:" + file.name;
9 }
10 var request:URLRequest = new URLRequest();
11 request.url="http://localhost/Web/UpLoadHandler.ashx";
12 file.upload(request);
13 }
寫(xiě)好了upload方法,現(xiàn)在就是調(diào)用他了,通過(guò)按扭的click事件直接調(diào)用就可以,另外調(diào)用file.browse()方法則實(shí)現(xiàn)選擇文件的功能,如下mxml代碼描述:
2 <mx:Button x="247" y="57" label="選擇" fontWeight="normal" click="{file.browse()}"/>
3 <mx:Button x="29" y="111" label="上傳文件" width="111" fontWeight="normal" click="onUpLoad()"/>
如上便完成了上傳文件的Flex客戶端開(kāi)發(fā),通過(guò)file.upload()方法,將把選擇的文件通過(guò)二進(jìn)制的形式發(fā)送到指定的服務(wù)端,并自動(dòng)傳遞一個(gè)叫“fileName”的參數(shù),服務(wù)端通過(guò)fileName便可以接收到客戶端請(qǐng)求上傳的文件。最后我們來(lái)看看服務(wù)端的 UpLoadHandler.ashx的詳細(xì)定義:
2 {
3 //文件上傳目錄
4 private string uploadFolder = "UpLoad";
5
6 public void ProcessRequest(HttpContext context)
7 {
8 context.Response.ContentType = "text/plain";
9
10 HttpFileCollection files = context.Request.Files;
11 if (files.Count > 0)
12 {
13 string path = context.Server.MapPath(uploadFolder);
14 HttpPostedFile file = files[0];
15
16 if (file != null && file.ContentLength > 0)
17 {
18 string savePath = path + "/" + context.Request.Form["fileName"];
19 file.SaveAs(savePath);
20 }
21 }
22 else
23 {
24 context.Response.Write("參數(shù)錯(cuò)誤");
25 context.Response.End();
26 }
27 }
28
29 public bool IsReusable
30 {
31 get
32 {
33 return false;
34 }
35 }
36 }
如上一系列的步驟便可完成上傳文件的功能,下面便是上傳文件示例程序運(yùn)行截圖:
實(shí)現(xiàn)了文件上傳下面來(lái)看看怎么實(shí)現(xiàn)文件下載, 以上面上傳示例中上傳的mp3為例,下面我們來(lái)看看怎么從服務(wù)器(http://localhost/Web/UpLoad/做你的愛(ài)人.mp3)上完成文件(做你的愛(ài)人.mp3)的下載。
要實(shí)現(xiàn)文件下載對(duì)服務(wù)器端只要保證被下載文件存在就OK,同上傳文件一樣需要實(shí)例化一個(gè)FielReference對(duì)象的實(shí)例,并為其添加相應(yīng)的事件處理函數(shù):
2 * createChildren 比 creationComplete 事件更早發(fā)生
3 * */
4 protected override function createChildren():void
5 {
6 super.createChildren();
7 file.addEventListener(Event.SELECT,onSelected);
8 file.addEventListener(Event.COMPLETE,onCompleted);
9 file.addEventListener(ProgressEvent.PROGRESS,onProgress);
10 //實(shí)現(xiàn)文件下載
11 fileDown.addEventListener(Event.COMPLETE,onDownCompleted);
12 fileDown.addEventListener(ProgressEvent.PROGRESS,onDownProgress);
13 }
如上為實(shí)現(xiàn)下載文件的實(shí)例fileDown注冊(cè)了成功下載文件后事件處理函數(shù)和下載過(guò)程處理函數(shù),下面是兩個(gè)方法的詳細(xì)定義:
2 {
3 var fileRef:FileReference = evt.currentTarget as FileReference;
4 resultLabel.text = "文件名:" + fileRef.name + "下載完畢!";
5 }
6
7 internal function onDownProgress(evt:ProgressEvent):void
8 {
9 downState.text = "已下載: " + Math.round(100 * evt.bytesLoaded / evt.bytesTotal) + "%";
10 }
完成了對(duì)象事件的開(kāi)發(fā),最后便上懲罰下載請(qǐng)求了,直接調(diào)用FileReference類(lèi)所提供的download()方法既可:
2 * 調(diào)用FileReference類(lèi)的實(shí)例方法download()實(shí)現(xiàn)文件下載
3 * */
4 internal function onDownLoad():void
5 {
6 var request:URLRequest = new URLRequest();
7 request.url="http://localhost:1146/UpLoad/做你的愛(ài)人.mp3";
8 fileDown.download(request);
9 }
程序執(zhí)行到download()方法的時(shí)候會(huì)自動(dòng)彈出選擇保存文件對(duì)話框,根據(jù)實(shí)際情況選擇好保存路徑就OK。下面是實(shí)現(xiàn)上傳和下載的完整代碼:


1 <?xml version="1.0" encoding="utf-8"?>
2 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
3 <mx:Panel x="49" y="66" width="551" height="164" layout="absolute"
4 title="使用FileReference上傳/下載文件" fontSize="12">
5 <mx:HDividedBox x="10" y="10" width="511" height="102">
6 <mx:Canvas id="left" backgroundColor="#D7F4FF" height="100%" width="209">
7 <mx:TextInput x="4" y="20" id="txtFile" text="{stateText}" width="135"/>
8 <mx:Button x="147" y="20" label="選擇" fontWeight="normal" click="{file.browse()}"/>
9 <mx:Button x="31" y="68" label="上傳文件" width="111" fontWeight="normal" click="onUpLoad()"/>
10 </mx:Canvas>
11 <mx:Canvas id="right" backgroundColor="#D7F4FF" height="100%" width="282">
12 <mx:Label x="6" y="9" text="http://localhost/Web/UpLoad/做你的愛(ài)人.mp3"/>
13 <mx:Button x="10" y="37" label="下載文件" fontWeight="normal" click="onDownLoad()"/>
14 <mx:Label x="10" y="74" width="272" id="resultLabel"/>
15 <mx:TextInput x="122" y="
16 </mx:Canvas>
17 </mx:HDividedBox>
18
19 </mx:Panel>
20 <mx:Script>
21 <![CDATA[
22 [Bindable]
23 private var stateText:String = "請(qǐng)選擇一個(gè)文件上傳";
24
25 private var file:FileReference = new FileReference();
26 private var fileDown:FileReference = new FileReference();
27
28 /**
29 * createChildren 比 creationComplete 事件更早發(fā)生
30 * */
31 protected override function createChildren():void
32 {
33 super.createChildren();
34 file.addEventListener(Event.SELECT,onSelected);
35 file.addEventListener(Event.COMPLETE,onCompleted);
36 file.addEventListener(ProgressEvent.PROGRESS,onProgress);
37
38 fileDown.addEventListener(Event.COMPLETE,onDownCompleted);
39 fileDown.addEventListener(ProgressEvent.PROGRESS,onDownProgress);
40 }
41
42 // internal function initApp():void
43 // {
44 // file.addEventListener(Event.SELECT,onSelected);
45 // file.addEventListener(Event.COMPLETE,onCompleted);
46 // file.addEventListener(ProgressEvent.PROGRESS,onProgress);
47 // }
48
49 internal function onSelected(evt:Event):void
50 {
51 stateText = "選擇了文件:" + file.name;
52 }
53
54 internal function onCompleted(evt:Event):void
55 {
56 stateText = "上傳完畢!";
57 }
58
59
60 internal function onDownCompleted(evt:Event):void
61 {
62 var fileRef:FileReference = evt.currentTarget as FileReference;
63 resultLabel.text = "文件名:" + fileRef.name + "下載完畢!";
64 }
65
66 internal function onProgress(evt:ProgressEvent):void
67 {
68 stateText = "已上傳: " + Math.round(100 * evt.bytesLoaded / evt.bytesTotal) + "%";
69
70 }
71
72 internal function onDownProgress(evt:ProgressEvent):void
73 {
74 downState.text = "已下載: " + Math.round(100 * evt.bytesLoaded / evt.bytesTotal) + "%";
75 }
76
77 /**
78 * 調(diào)用FileReference的實(shí)例方法upload()實(shí)現(xiàn)文件上傳
79 * */
80 internal function onUpLoad():void
81 {
82 if(file.size > 0)
83 {
84 stateText = "正在上傳文件:" + file.name;
85 }
86 var request:URLRequest = new URLRequest();
87 request.url=http://localhost/Web/UpLoadHandler.ashx;
88 file.upload(request);
89 }
90
91 /**
92 * 調(diào)用FileReference類(lèi)的實(shí)例方法download()實(shí)現(xiàn)文件下載
93 * */
94 internal function onDownLoad():void
95 {
96 var request:URLRequest = new URLRequest();
97 request.url="http://localhost/Web/UpLoad/做你的愛(ài)人.mp3";
98 fileDown.download(request);
99 }
100 ]]>
101 </mx:Script>
102 </mx:Application>
103
程序運(yùn)行截圖:
16 </mx:Canvas>
17 </mx:HDividedBox>
18
19 </mx:Panel>
20 <mx:Script>
21 <![CDATA[
22 [Bindable]
23 private var stateText:String = "請(qǐng)選擇一個(gè)文件上傳";
24
25 private var file:FileReference = new FileReference();
26 private var fileDown:FileReference = new FileReference();
27
28 /**
29 * createChildren 比 creationComplete 事件更早發(fā)生
30 * */
31 protected override function createChildren():void
32 {
33 super.createChildren();
34 file.addEventListener(Event.SELECT,onSelected);
35 file.addEventListener(Event.COMPLETE,onCompleted);
36 file.addEventListener(ProgressEvent.PROGRESS,onProgress);
37
38 fileDown.addEventListener(Event.COMPLETE,onDownCompleted);
39 fileDown.addEventListener(ProgressEvent.PROGRESS,onDownProgress);
40 }
41
42 // internal function initApp():void
43 // {
44 // file.addEventListener(Event.SELECT,onSelected);
45 // file.addEventListener(Event.COMPLETE,onCompleted);
46 // file.addEventListener(ProgressEvent.PROGRESS,onProgress);
47 // }
48
49 internal function onSelected(evt:Event):void
50 {
51 stateText = "選擇了文件:" + file.name;
52 }
53
54 internal function onCompleted(evt:Event):void
55 {
56 stateText = "上傳完畢!";
57 }
58
59
60 internal function onDownCompleted(evt:Event):void
61 {
62 var fileRef:FileReference = evt.currentTarget as FileReference;
63 resultLabel.text = "文件名:" + fileRef.name + "下載完畢!";
64 }
65
66 internal function onProgress(evt:ProgressEvent):void
67 {
68 stateText = "已上傳: " + Math.round(100 * evt.bytesLoaded / evt.bytesTotal) + "%";
69
70 }
71
72 internal function onDownProgress(evt:ProgressEvent):void
73 {
74 downState.text = "已下載: " + Math.round(100 * evt.bytesLoaded / evt.bytesTotal) + "%";
75 }
76
77 /**
78 * 調(diào)用FileReference的實(shí)例方法upload()實(shí)現(xiàn)文件上傳
79 * */
80 internal function onUpLoad():void
81 {
82 if(file.size > 0)
83 {
84 stateText = "正在上傳文件:" + file.name;
85 }
86 var request:URLRequest = new URLRequest();
87 request.url=http://localhost/Web/UpLoadHandler.ashx;
88 file.upload(request);
89 }
90
91 /**
92 * 調(diào)用FileReference類(lèi)的實(shí)例方法download()實(shí)現(xiàn)文件下載
93 * */
94 internal function onDownLoad():void
95 {
96 var request:URLRequest = new URLRequest();
97 request.url="http://localhost/Web/UpLoad/做你的愛(ài)人.mp3";
98 fileDown.download(request);
99 }
100 ]]>
101 </mx:Script>
102 </mx:Application>
103
程序運(yùn)行截圖:
- asp.net 多文件上傳,兼容IE6/7/8,提供完整代碼下載
- asp.net Web Services上傳和下載文件(完整代碼)
- Asp.net實(shí)現(xiàn)MVC處理文件的上傳下載功能實(shí)例教程
- asp.net 上傳下載輸出二進(jìn)制流實(shí)現(xiàn)代碼
- asp.net 上傳或下載當(dāng)文件名包含有特殊字符"#"的處理
- ASP.NET中文件上傳下載方法集合
- asp.net+jquery.form實(shí)現(xiàn)圖片異步上傳的方法(附j(luò)query.form.js下載)
- .NET實(shí)現(xiàn)微信公共平臺(tái)上傳下載多媒體文件
- 擁有網(wǎng)頁(yè)版小U盤(pán) ASP.NET實(shí)現(xiàn)文件上傳與下載功能
- .NET實(shí)現(xiàn)文件跨服務(wù)器上傳下載的方法