ایجاد آپلود چند فایل و اعتبار سنجی به صورت داینامیک در 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
- 3k بازدید
- 11 تشکر