[ASP.net MVC] 上傳檔案時不要連同表單都提交

[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觀看結果
        }

    }
}

執行結果流程:

預設畫面

image

上傳檔案後:

image

(表單沒有一起被提交)

接下來按”提交”表單,查看結果

image

再度Get Method回到表單,TempData確實有被清空

image

 

不過這種做法目前觀察有兩個缺點:

1.一個上傳控制項就對應一個Session,在表單內同時嵌入好幾個上傳的View,Session會蓋來蓋去導致新增至資料庫時的資訊是錯誤的

2.而且預覽圖片要是過大,iframe有可能出現捲軸

 

Sample Code