在asp.net WebForm當中找個簡單的方法實現非同步檔案上傳

最近由於一些因緣際會,又得回頭寫一點asp.net WebForm相關的東西,但,時代在這5年中實在有了不少的改變,因此一些過去的做法,最近有了不同的實作方式,其實我也是久久沒用怕忘記,紀錄一下。

我們最近碰到一個需求,非常單純,就是希望在網頁上用非同步的方式上傳檔案。

這需求沒啥好說嘴的,對吧。

但環境是這樣的,我們用的開發工具是asp.net WebForm,頁面需要盡可能保持單純,因為我自己不喜歡任何從伺服器端render html到前端的解決方案,因此一開始就盡可能的少用 web control之類的東西。由於現在有jQuery可用,瀏覽器的支援也比當年好了不知多少倍,因此,asp.net AJAX那種龐然大物自然也被排除在選用範圍之外。

為何不用asp.net MVC? 一則因為網站必須和過去開發環境(人員)相容,另外asp.net MVC中的Razor view也會從伺服器端render html到前端,route的對應方式和過去webForm的路徑作法不同,在一個專案裡面同時出現實在太不直覺,因此也不在考慮範圍內。

但專案中我們會用asp.net WebApi,如果需要的話(這表示我們不用Web/WCF Services了)。

簡單的說,就是這雖然用asp.net WebForm技術,但頁面前端盡可能的只有 html 與 js,而後端用C#,盡量不用任何WebControls。OK,背景交代完畢。

怎麼實現,先看前端要怎麼上傳檔案,很簡單,放一個file upload,和一個上傳button,寫一點js做非同步上傳用:

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script>
//傳入FileControl,配合在asp.net的page load當中
function UploadFileAsync(FileControl) {
var formData = new FormData();
//抓取File Control中的檔案
var file = FileControl.files[0];
formData.append("file", file);
//非同步post給自己
var uploadServerSideScriptPath = window.location.href;
var xhr = new XMLHttpRequest();
xhr.open("POST", uploadServerSideScriptPath, false);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", file.name);
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("X-File-Type", file.type);
//如果狀態改變了
xhr.onreadystatechange = function () {
//如果完成了
if (xhr.readyState == XMLHttpRequest.DONE) {
//顯示個訊息
alert(xhr.responseText);
}
}
xhr.send(formData);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="file" id="filecontrol" />
<input type="button" onclick="UploadFileAsync(document.getElementById('filecontrol'));" value="Upload File" />
</div>
</form>
</body>
</html>

我覺得大部分的程式碼都不需要解釋,留意31行body之後,雖然該頁面是asp.net webform,但除了預設的form tag之外,其他的control我們都是用html而非asp.net web controls,在button click時候,我們呼叫第6行的UploadFileAsync,裡面透過很標準的post方法把用戶選擇的檔案上傳。

就這樣。

那伺服器端怎麼接這個檔案呢? 也容易:

protected void Page_Load(object sender, EventArgs e)
{
HttpPostedFile file = null;
if (Request.Files.Count > 0)
{
//找到檔案
file = Request.Files[0];
//儲存
var filePath = Server.MapPath(System.IO.Path.GetFileName(file.FileName));
file.SaveAs(filePath);
//回應訊息
Response.Write(filePath + " saved.");
Response.End();
}
}
就上面這區區幾行…

ㄟ…我承認,放在Page_Load裡面看起來有點low,但,這是最簡單單純的做法了,整個過程中不需要使用任何第三方套件或工具,頁面也盡可能保持乾淨。

結案,收工。

喔,程式碼在https://github.com/isdaviddong/AspNetWebFormAsyncFileUpload

後記 :

  1. 其實比較有趣的是,透過上面這樣的Code,你很容易猜出asp.net WebForm當中檔案上傳這個機制骨子裡的做法。
  2. github的gist還蠻好用的。
  3. asp.net WebForm用的好,搭配一點js,無須什麼新技術,其實日子也可以蠻好過的。

留言

匿名表示…
onclick="UploadFileAsync(document.getElementById('filecontrol'));"

應該是onclientclick 嗎??
艾克寫道…
onclientclick 是 WebControl 的事件定義方式
在 Html input 用 onclick 即可

這個網誌中的熱門文章

使用LM Studio輕鬆在本地端以API呼叫大語言模型(LLM)

實際嘗試使用DeepSeek API

使用 Dify 以No Code方式建立記帳機器人

使用 Dify API 快速建立一個包含前後文記憶的對談機器人

使用 Dify 建立企業請假機器人