[ASP.net MVC] 上傳檔案時不要連同表單都提交
先看一般如果有一個表單,需要填寫上傳附加檔案時
填寫完姓名,也選擇了上傳檔案
這時候按”提交”,Controller新增資料到資料庫,也把檔案上傳至WebServer,然後導向結果頁
這時候客戶可能有個需求,要是想在上傳檔案後,預覽圖片或顯示檔案路徑可以讓人確認上傳有無錯誤(也就是上傳檔案不要連表單都一同提交)
問題來源:http://social.msdn.microsoft.com/Forums/zh-TW/236/thread/d2f548e3-0aff-4602-af74-e3eb0d454bca
這種情況就得使用iframe嵌上傳的View(可別為了此小小需求特地去學Silverlight或找jQuery套件^_^”)
要填寫的Form表單View
2011.7.29 再度改寫程式
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Index</title>
</head>
<body>
<% using (Html.BeginForm("Save","Form",FormMethod.Post)){%>
<%= Html.Label("姓名") %>:
<%= Html.TextBox("name") %><br />
<!--上傳功能嵌入iframe-->
<div style="height:150px">
<iframe src="/Upload/Index" height="100%" width="250px" frameborder="0" scrolling="no">
</iframe>
</div>
<input type="submit" name="submit1" value="提交" />
<% } %>
</body>
</html>
嵌入上傳功能的View
<html>
<body>
<% using (Html.BeginForm("UploadFile", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" })) { %>
<%=Html.Label("上傳檔案") %>
<br />
<input type="file" id="file1" name="file1" /><br />
<input type="submit" value="上傳" /><br />
預覽圖片:
<% if (TempData["fileUrl"] != null) { %>
<img src="<%: TempData["fileUrl"] %>" width="50" height="50" alt="預覽圖" />
<% } %>
<% } %>
</body>
</html>
上傳功能的Controller
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcUploadImg.Controllers
{
public class UploadController : Controller
{
//Get
public ActionResult Index()
{
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UploadFile(HttpPostedFileBase file1)
{
//有檔案上傳時
if (file1!=null)
{
string filename = file1.FileName;//取得原始檔名
string extension = System.IO.Path.GetExtension(filename);//取得原始檔案副檔名
string newFileName = Guid.NewGuid().ToString() + extension;//這是新檔名,避免上傳的檔名重覆
file1.SaveAs(Server.MapPath("~/upload/" + newFileName));//上傳檔案至WebServer
TempData["fileUrl"] = "/upload/" + newFileName;//上傳完圖片預覽用
Session["fileName"] = newFileName;//要給其他Controller寫入資料庫用的fileName,存在Session裡
}
return View("Index");//直接回傳View
}
}
}
表單提交的Controller
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcUploadImg.Controllers
{
public class FormController : Controller
{
//
// GET: /Form/
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Save(string name)
{
//把name參數 和 Session["fileName"]新增到資料庫...
//導向結果頁
TempData["name"] = name;
return View("Result");//到Result View觀看結果
}
}
}
執行結果流程:
預設畫面
上傳檔案後:
(表單沒有一起被提交)
接下來按”提交”表單,查看結果
再度Get Method回到表單,TempData確實有被清空
不過這種做法目前觀察有兩個缺點:
1.一個上傳控制項就對應一個Session,在表單內同時嵌入好幾個上傳的View,Session會蓋來蓋去導致新增至資料庫時的資訊是錯誤的
2.而且預覽圖片要是過大,iframe有可能出現捲軸