در این بین راه حل دیگری نیز وجود دارد که با تمام مرورگرها سازگار است؛ اما تنها گزارش درصد آپلود را توسط آن نخواهیم داشت. در اینجا به صورت پویا یک IFrame مخفی در صفحه تشکیل میشود، مقادیر معمولی فرم (تمام المانها، منهای file) به صورت Ajax ایی به سرور ارسال خواهند شد. المان file آن در این IFrame مخفی، به صورت معمولی به سرور Postback میشود. البته کاربر در این بین چیزی را مشاهده یا احساس نخواهد کرد و تمام عملیات از دیدگاه او Ajax ایی به نظر میرسد. برای انجام اینکار تنها کافی است از افزونهی AjaxFileUpload استفاده کنیم که در ادامه نحوهی استفاده از آنرا بررسی خواهیم کرد.
پیشنیازها
در ادامه فرض بر این است که افزونهی AjaxFileUpload را دریافت کرده و به فایل Layout برنامه افزودهاید:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - My ASP.NET Application</title> <link href="~/Content/Site.css" rel="stylesheet" type="text/css" /> </head> <body> <div> @RenderBody() </div> <script src="~/Scripts/jquery-1.11.1.min.js"></script> <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script> <script src="~/Scripts/ajaxfileupload.js"></script> @RenderSection("Scripts", required: false) </body> </html>
مدل، کنترلر و View برنامه
مدل برنامه مشخصات یک محصول است:
namespace MVCAjaxFormUpload.Models { public class Product { public int Id { set; get; } public string Name { set; get; } } }
کنترلر آن از سه متد تشکیل شدهاست:
using System.Threading; using System.Web; using System.Web.Mvc; using MVCAjaxFormUpload.Models; namespace MVCAjaxFormUpload.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index(Product product) { var isAjax = this.Request.IsAjaxRequest(); return Json(new { result = "ok" }, JsonRequestBehavior.AllowGet); } [HttpPost] public ActionResult UploadFiles(HttpPostedFileBase image1, int id) { var isAjax = this.Request.IsAjaxRequest(); Thread.Sleep(3000); //شبیه سازی عملیات طولانی return Json(new { FileName = "/Uploads/filename.ext" }, "text/html", JsonRequestBehavior.AllowGet); } } }
Index دوم کار پردازش Ajax ایی اطلاعات ارسالی به سرور را به عهده دارد. HttpPost آن Ajax ایی است.
متد UploadFiles، کار پردازش اطلاعات ارسالی از طرف IFrame مخفی را انجام میدهد. HttpPost آن معمولی است.
و کدهای View این مثال نیز به شرح زیر است:
@model MVCAjaxFormUpload.Models.Product @{ ViewBag.Title = "Index"; } <h2>Ajax Form Upload</h2> @using (Ajax.BeginForm(actionName: "Index", controllerName: "Home", ajaxOptions: new AjaxOptions { HttpMethod = "POST" }, routeValues: null, htmlAttributes: new { id = "uploadForm" })) { <label>Name:</label> @Html.TextBoxFor(model => model.Name) <br /> <label>Image:</label> <br /> <input type="file" name="Image1" id="Image1" /> <br /> <input type="submit" value="Submit" /> <img id="loading" src="~/Content/Images/loading.gif" style="display:none;"> } @section Scripts { <script type="text/javascript"> $(function () { $('#uploadForm').submit(function () { $("#loading").show(); $.ajaxFileUpload({ url: "@Url.Action("UploadFiles", "Home")", // مسیری که باید فایل به آن ارسال شود secureuri: false, fileElementId: 'Image1', // آی دی المان ورودی فایل dataType: 'json', data: { id: 1, data: 'test' }, // اطلاعات اضافی در صورت نیاز success: function (data, status) { $("#loading").hide(); if (typeof (data.FileName) != 'undefined') { alert(data.FileName); } }, error: function (data, status, e) { $("#loading").hide(); alert(e); } }); }); }); </script> }
در ادامه نحوهی فعال سازی ajaxFileUpload را دقیقا در زمان submit فرم، مشاهده میکنید. در اینجا url آن به اکشن متدی که اطلاعات المان file را باید دریافت کند، اشاره میکند. fileElementId آن مساوی Id المان فایل فرم Ajax ایی صفحهاست. از قسمت data جهت ارسال اطلاعات اضافهتری به اکشن متد UploadFiles استفاده میشود. سایر قسمتهای آن نیز مشخص هستند. اگر عملیات موفقیت آمیز بود، success آن و اگر خیر، error آن اجرا میشوند.
فقط باید دقت داشت که content type دریافتی توسط آن باید text/html باشد، که این مورد در اکشن متدهای کنترلر مشخص هستند.
به این ترتیب دیگر کاربر نیازی ندارد ابتدا یکبار بر روی دکمهی دومی کلیک کرده و فایل را ارسال کند و سپس بار دیگر بر روی دکمهی submit فرم کلیک نماید. هر دو کار توسط یک دکمه انجام میشوند.
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید
MVCAjaxFormUpload.zip