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

چهارشنبه 28 مهر 1395

در این مقاله ، هدف ما آموزش ایجاد برنامه 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

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید