ایجاد آپلود چند فایل و اعتبار سنجی به صورت داینامیک در MVC
چهارشنبه 28 مهر 1395در این مقاله ، هدف ما آموزش ایجاد برنامه Dynamic آپلود چند فایل در MVC و اعتبارسنجی آنها میباشد . اگر در گوگل در مورد مثال های آپلود عکس در MVC جستجو کنید ، مثال های بسیاری را یافت خواهید ، اما وجه مشترک همه آن مثال ها این است که شما فقط قادر به آپلود یک فایل میباشید ، که ما این را نمیخواهیم . هدف ما از ارائه این مقاله آموزش ایجاد یک برنامه با قابلیت آپلود چند فایل است .
اگر یک کاربر یک فرمی را برای گواهینامه رانندگی خود پر میکند ، نیازمند این است که بیش از یک اسناد را آپلود کند . مثلا شناسنامه ، کارت ملی و ... . ما برای آپلود این اسناد دو صفحه جدا ایجاد نمیکنیم بلکه ، آن را بصورت پویا در یک تک صفحه پیاده میکنیم .
ابزارهای مورد نیاز :
• SQL Server
• Visual Studio 2010 یا نسخه های بالاتر
ایجاد آپلود چند فایل :
اجازه دهید کار را با ایجاد یک برنامه Basic در MVC ایجاد کنیم . بعد از باز کردن Visual Studio ، یک پروژه Web Application با Empty Template با نام MultipleUploads ایجاد کنید . تصاویر زیر را مشاهده کنید .
بعد از چند ثانیه ، پروژه شما ساخته میشود . پروژه ایجاد شده شما ، شامل تمام فولدر های ساختاری MVC نظیر Script و CSS میباشد . Solution Explorer پروژه شما بصورت زیر خواهد شد :
حال به سراغ اضافه کردن ، Controller میرویم :
بعد از ایجاد پروژه ، به سراغ ایجاد Controllerای با نام DocumentsController میرویم که در خواست های Get و Post را مدیریت میکند .
اضافه کردن Model :
در این مرحله ، به سراغ اضافه کردن Modelای با نام DocumentModel میرویم . این Model مشخصه هایی همچون DocumentID, DocumentName, و Mandatory خواهد داشت .
برای اضافه کردن Model ، کافیست روی فولدر Model راست کلیلک کرده و یک کلاس به ان اضافه کنید :
کدهای لازم برای کلاس Model :
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MultipleUploads.Models { public class DocumentModel { public int DocumentID { get; set; } public string DocumentName { get; set; } public int Mandatory { get; set; } public List<DocumentModel> DocumentList { get; set; } } }
مشخصه ها :
• DocumentID منحصر به فرد است .
• DocumentName نام سندی است که قرار است ، آپلود شود .
• Mandatory مشخصه ای است که مشخص میکند ، آپلود کردن این سند اجباری است یا نه .
• DocumentList شامل لیستی از اسناد است که ما قصد ارسال آن را داریم .
بعد از اضافه کردن Model ، به سراغ تغییر نام Action Methodهای Controller میرویم . index را به Upload تغییر دهید و یک متد دیگر برای مدیریت درخواست های Post به Controller اضافه کنید که DocumentModel را به عنوان پارامتر ورودی دریافت میکند :
using MultipleUploads.Models; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MultipleUploads.Controllers { public class DocumentsController : Controller { // // GET: /Documents/ [HttpGet] public ActionResult Upload() { return View(); } [HttpPost] public ActionResult Upload(DocumentModel DocumentModel) { return View(); } } }
بعد از ایجاد متدهایی برای مدیریت درخواست های Get و Post ، حال به سراغ ایجاد مجموعه ای از اسناد برای متد Get میرویم .
نکته : چون این مثال ما آزمایشی است ، ما این مجموعه را اضافه میکنیم . وگرنه این باید به پایگاه داده متصل باشد .
using MultipleUploads.Models; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MultipleUploads.Controllers { public class DocumentsController : Controller { // // GET: /Documents/ [HttpGet] public ActionResult Upload() { DocumentModel objdocument = new DocumentModel(); objdocument.DocumentList = new List<DocumentModel> { new DocumentModel { DocumentID = 1,DocumentName ="PANCard", Mandatory=1 }, new DocumentModel { DocumentID = 2,DocumentName ="IncomeTax", Mandatory=0}, new DocumentModel { DocumentID = 3,DocumentName ="PassPortID", Mandatory=1 }, new DocumentModel { DocumentID = 4,DocumentName ="Driving_Licence", Mandatory=1 } }; return View(objdocument); } [HttpPost] public ActionResult Upload(DocumentModel DocumentModel) { return View(); } } }
در مرحله بعدی ، به سراغ View میرویم :
برای اضافه کردن View ، فقط کافیست که روی Upload کلیک راست کرده و از لیست باز شده
Add View را انتخاب کنید .
در مرحله بعد ، پنجره ای با نام Add View باز خواهد شد . بصورت پیش فرض View هم نام با Controller است . View Engine را Razor انتخاب کنید و Model خود را انتخاب کنید .
ساختار Solution Explorer بعد از اضافه کردن View بصورت زیر خواهد بود :
بعد از اضافه کردن View ، حال به سراغ اضافه کردن کدهای آن میرویم :
در این مرحله ، ما به سراغ ایجاد کنترل Upload File میرویم . برای این کار ، ما از مشخصه های DocumentModel که توسط Controller به فرم ارسال میشود ، استفاده میکنیم .
@model MultipleUploads.Models.DocumentModel @ { Layout = null; } Model which is going to received upload View. Code snippet @using(Html.BeginForm("Upload", "Documents", FormMethod.Post, new { enctype = "multipart/form-data" })) {}
Html.BeginForm همانند همان tag form است و ما در آن Action name و controller name را مشخص کرده ایم . هدف ما Post کردن این داده ها است . برای این کار ، ما از متد [ FormMethod.Post] استفاده میکنیم و در آخر صفت enctype برای encode کردن داده ها مورد استفاده قرار میگیرد .
نکته : enctype چگونگی encode شدن داده های form را در هنگام ارسال مشخص میکند .
تکه کدی برای upload view :
if (Model.DocumentList != null) { for (int i = 0; i < Model.DocumentList.Count; i++) { var fileupload1 = "file_" + Convert.ToString(Model.DocumentList[i].DocumentID); var hdnlbl1 = "hdnlbl_" + Convert.ToString(Model.DocumentList[i].DocumentID); var hdn1 = "hdn1_" + Convert.ToString(Model.DocumentList[i].DocumentID); var madname = "manddocname_" + Convert.ToString(Model.DocumentList[i].DocumentID); var valdation = "_val" + Convert.ToString(Model.DocumentList[i].DocumentID); if (Model.DocumentList[i].Mandatory != null) { var mad = "mand_" + i; @Html.HiddenFor(m => m.DocumentList[i].Mandatory, new { id = mad }) } @{ var documentname = Model.DocumentList[i].DocumentName;} @Html.HiddenFor(m => m.DocumentList[i].DocumentName, new { id = hdnlbl1 }) @Html.HiddenFor(m => m.DocumentList[i].DocumentID, new { id = hdn1 }) @Html.HiddenFor(m => m.DocumentList[i].DocumentName, new { id = madname }) <div class="row"> <div class="col-md-3"> @if (Model.DocumentList[i].Mandatory == 1) { <label style="color: red;">*</label> } <label style="font-size: 15px;">@documentname</label> <span class="btn btn-info btn-file"> <input type="file" id="@fileupload1" name="@fileupload1" onchange="ValidateFile(this);" /> </span> <span style="color:Red" id=@valdation></span> </div> </div> <br /> } }
در این قسمت ما قصد چک کردن Model را داریم که که ببینیم model ما null هست یا نه . بعد از آن ، ما با استفاده از یک حلقه ، کنترل file upload را برای لیستی از اسناد که از action method ارسال میشوند ، تولید میکنیم .
if (Model.DocumentList != null) { for (int i = 0; i < Model.DocumentList.Count; i++) { } }
سپس ، ما یک id منحصر بفرد برای انتساب به Control تولید میکنیم ، به این دلیل که هر Control باید یک شناسه منحصر به فرد داشته باشد تا بتوان آن را شناسایی کرد .
var fileupload1 = "file_" + Convert.ToString(Model.DocumentList[i].DocumentID); var hdnlbl1 = "hdnlbl_" + Convert.ToString(Model.DocumentList[i].DocumentID); var hdn1 = "hdn1_" + Convert.ToString(Model.DocumentList[i].DocumentID); var madname = "manddocname_" + Convert.ToString(Model.DocumentList[i].DocumentID); var valdation = "_val" + Convert.ToString(Model.DocumentList[i].DocumentID);
بعد از ایجاد این شناسه منحصر به فرد ، ما این شناسه را به hidden dieldها انتساب میدهیم که به ما در دریافت داده ها در سرور در Action method کمک میکند .
if (Model.DocumentList[i].Mandatory != null) { var mad = "mand_" + i; @Html.HiddenFor(m => m.DocumentList[i].Mandatory, new { id = mad }) } @{ var documentname = Model.DocumentList[i].DocumentName;} @Html.HiddenFor(m => m.DocumentList[i].DocumentName, new { id = hdnlbl1 }) @Html.HiddenFor(m => m.DocumentList[i].DocumentID, new { id = hdn1 }) @Html.HiddenFor(m => m.DocumentList[i].DocumentName, new { id = madname })
بعد از انتساب مقادیر به hidden fieldها ، حال به سراغ ایجاد کنترل file upload می رویم . label برای نمایش نام اسناد ، همچنین در صورت اجباری بودن فیلد یک ستاره در کنار اسم آن نمایش خواهید داد .
<div class="row"> <div class="col-md-3"> @if (Model.DocumentList[i].Mandatory == 1) { <label style="color: red;">*</label> } @{ var documentname = Model.DocumentList[i].DocumentName;} <label style="font-size: 15px;">@documentname</label> <span class="btn btn-info btn-file"> <input type="file" id="@fileupload1" name="@fileupload1" onchange="ValidateFile(this);" /> </span> <span style="color:Red" id=@valdation></span> </div> </div> Finally we require submit but to post form to server. <div style="margin-top: 20px;" class="col-sm-4 col-xs-12 col-lg-6 col-md-4"> <input id="Submit1" class="btn btn-success" type="submit" onclick="return Savefiles();" value=" submit" /> </div>
تکه کد برای Upload View :
<div class="container"> <div style="margin-top: 20px;" class="row"> <div class="col-sm-4 col-xs-12 col-lg-6 col-md-4"> </div> </div> <div class="panel panel-default"> <div class="panel-heading">@Html.Label("Upload Documents")</div> <div class="panel-body"> @using (Html.BeginForm("Upload", "Documents", FormMethod.Post, new { id = "TheForm", enctype = "multipart/form-data" })) { if (Model.DocumentList != null) { for (int i = 0; i < Model.DocumentList.Count; i++) { var fileupload1 = "file_" + Convert.ToString(Model.DocumentList[i].DocumentID); var hdnlbl1 = "hdnlbl_" + Convert.ToString(Model.DocumentList[i].DocumentID); var hdn1 = "hdn1_" + Convert.ToString(Model.DocumentList[i].DocumentID); if (Model.DocumentList[i].Mandatory != null) { var mad = "mand_" + i; @Html.HiddenFor(m => m.DocumentList[i].Mandatory, new { id = mad }) } var madname = "manddocname_" + Convert.ToString(Model.DocumentList[i].DocumentID); var valdation = "_val" + Convert.ToString(Model.DocumentList[i].DocumentID); @Html.HiddenFor(m => m.DocumentList[i].DocumentName, new { id = hdnlbl1 }) @Html.HiddenFor(m => m.DocumentList[i].DocumentID, new { id = hdn1 }) @Html.HiddenFor(m => m.DocumentList[i].DocumentName, new { id = madname }) <div class="row"> <div class="col-md-3"> @if (Model.DocumentList[i].Mandatory == 1) { <label style="color: red;">*</label> } @{ var documentname = Model.DocumentList[i].DocumentName;} <label style="font-size: 15px;">@documentname</label> <span class="btn btn-info btn-file"> <input type="file" id="@fileupload1" name="@fileupload1" onchange="ValidateFile(this);" /> </span> <span style="color:Red" id=@valdation></span> </div> </div> <br /> } } <div class="row"> <div class="col-sm-4 col-xs-12 col-lg-6 col-md-4"> </div> </div> <div style="margin-top: 20px;" class="col-sm-4 col-xs-12 col-lg-6 col-md-4"> <input id="Submit1" class="btn btn-success" type="submit" onclick="return Savefiles();" value=" submit" /> </div> } </div> </div> </div>
بعد از ایجاد کنترل ، از برنامه یک خروجی میگیریم :
در حال حاضر ما فقط کنترل ها را ایجاد کرده ایم و هیچ اعتبار سنجی ای روی آنها قرار نداده ایم .
اعتبارسنجی کنترل File Upload :
برای انجام اعتبار سنجی ، ما از javascript استفاده میکنیم :
1. ابتدا پسوند فایل را چک میکنیم که [.png ,jpg, jpeg, .pdf] باشد .
2. سایز فایلی که آپلود میشود باید کمتر از 1 مگابایت باشد .
3. اگر آپلود فایل اجباری تعریف شده است ، حتما باید فایلی در آن آپلود شود .
حال ، برای انجام کارهای بالا نیاز به کتابخانه های jQuery داریم :
Download: http://code.jquery.com/jquery-1.9.1.js
Download: http://code.jquery.com/jquery-migrate-1.2.1.js
ابتدا به سراغ اعتبارسنجی فایل میرویم . برای این کار ، از رویداد onchange در javascript استفاده میکنیم ، زمانی که فایلی انتخاب میشود ، این رویداد فراخوانی میشود و بدین معناست که شناسه فایل انتخابی را برای تابع ارسال میکند .
بعد از اینکه تابع ، شناسه فایل را دریافت کرد ، تابع [getNameFromPath] را فراخوانی میکند که آدرس فایل را بازمیگرداند . حال از طریق آدرس فایل ، ما میتوانید پسوند فایل را بررسی کنیم که معتبر است یا خیر . اگر نیست ، یک پیام خطا به کاربر نمایش داده شود . بعد از آن ما با فراخوانی تابع [ValidateFileSize] به سراغ بررسی سایز فایل میرویم که ببینیم معتبر است یا نه . اگر از نظر سایز مشکل داشت باز یک خطای دیگر نمایش داده شود و فایل حذف شود .
<input type="file" id="@fileupload1" name="@fileupload1" onchange="ValidateFile(this);" />
تکه کد کامل اعتبار سنجی فایل آپلود شده را در زیر مشاهده میکنید :
function ValidateFile(value) { var file = getNameFromPath($(value).val()); if (file != null) { var extension = file.substr((file.lastIndexOf('.') + 1)); switch (extension) { case 'jpg': case 'jpeg': case 'png': case 'pdf': flag = true; break; default: flag = false; } } if (flag == false) { var str = value.name; var res = str.split("_"); var data = "_val" + res[1]; $("#" + data).text("You can upload only jpg, jpeg, png, pdf extension file Only"); $("#" + value.name).val(''); return false; } else { var size = ValidateFileSize(value); var str = value.name; var res = str.split("_"); var data = "_val" + res[1]; if (size > 1) { $("#" + data).text("You Can Upload file Size Up to 1 MB."); $("#" + value.name).val(''); } else { $("#" + data).text(""); } } }
تکه کد کامل برای گرفتن نام فایل آپلود شده :
function getNameFromPath(strFilepath) { var objRE = new RegExp(/([^\/\\]+)$/); var strName = objRE.exec(strFilepath); if (strName == null) { return null; } else { return strName[0]; } }
تکه کد کامل برای بررسی سایز فایل آپلود شده :
function ValidateFileSize(fileid) { try { var fileSize = 0; if (navigator.userAgent.match(/msie/i)) { var obaxo = new ActiveXObject("Scripting.FileSystemObject"); var filePath = $("#" + fileid)[0].value; var objFile = obaxo.getFile(filePath); var fileSize = objFile.size; fileSize = fileSize / 1048576; } else { fileSize = $(fileid)[0].files[0].size fileSize = fileSize / 1048576; } return fileSize; } catch (e) { alert("Error is :" + e); } }
بعد از اعتبارسنجی تمام فایل ها ، در submit ما فیلدهای اجباری را بررسی میکنیم :
<input id="Submit1" class="btn btn-success" type="submit" onclick="return Savefiles();" value=" submit" /> Complete Code for checking mandatory files <script type="text/javascript"> function Savefiles() { var MandFlg = $("[id*='mand_']"); var FileUpload1 = $("[id*='file_']"); var madfile = $("[id*='manddocname_']"); var Booleandata = true; for (var i = 0; i < MandFlg.length; i++) { if ($("#" + MandFlg[i].id).val() == '1' && $("#" + FileUpload1[i].id).val() == '') { Booleandata = false; alert("Required " + $("#" + madfile[i].id).val()); } } return Booleandata; } </script>
حال زمانی که همه چیز معتبر است ، فایل ها را به سرور ارسال میکند .
بعد از ارسال فرم ، متد [upload [HttpPost فراخوانی میشود فایل های ارسالی را دریافت میکند ، در زیر داریم :
در متد Upload ، ما فقط فایل ها را دریافت و آنها را ذخیره خواهیم کرد . اگر کسی قصد ذخیره سازی عکس ها در فولدر خاصی را دارد ، توانایی انجام این امر را دارد .
تکه کد کامل برای [upload [HttpPost بصورت زیر است :
[HttpPost] public ActionResult Upload(DocumentModel DocumentModel) { var DocumentUpload = DocumentModel.DocumentList; foreach (var Doc in DocumentUpload) { string strFileUpload = "file_" + Convert.ToString(Doc.DocumentID); HttpPostedFileBase file = Request.Files[strFileUpload]; if (file != null && file.ContentLength > 0) { // if you want to save in folder use this var fileName = Path.GetFileName(file.FileName); var path = Path.Combine(Server.MapPath("~/Images/"), fileName); file.SaveAs(path); // if you want to store in Bytes in Database use this byte[] image = new byte[file.ContentLength]; file.InputStream.Read(image, 0, image.Length); } } return View(DocumentModel); }
آموزش asp.net mvc
- ASP.net MVC
- 2k بازدید
- 11 تشکر