ایجاد آپلود چند فایل و اعتبار سنجی به صورت داینامیک در MVC

در این مقاله ، هدف ما آموزش ایجاد برنامه Dynamic آپلود چند فایل در MVC و اعتبارسنجی آنها میباشد . اگر در گوگل در مورد مثال های آپلود عکس در 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

فایل های ضمیمه
دانلود نسخه ی PDF این مطلب