Angularjs

این مقاله نحوه آپلود چندگانه با استفاده از AngularJs و ASP.Net MVC و همچنین وضعیت پیشرفت آپلود فایل ها را به صورت جداگانه بررسی می کنیم.

مقدمه:

در این مقاله فرض بر این است که شما دانش استفاده از AngularJS را دارید. همچنین ما فرض کردیم که با Twitter Bootstrap، Font Awesome، HTML5 و CSS3 آشنا هستید.

گام ۱: آماده کردن فایل HTML و نمایش اطلاعات فایل انتخاب شده

در اینجا از تگ input برای آپلود چندگانه و آپلود تکی فایل استفاده می کنیم. کد HTML به شکل زیر خواهد بود:

html ng-app=AgApp
head
    meta name=viewport content=width=device-width /
    titleImageUploadMultiple/title
    link href=~/App_Content/CSS/bootstrap.min.css rel=stylesheet /
    link href=~/App_Content/CSS/font-awesome.min.css rel=stylesheet /
/head
body
     div class=col-md-12
        h2 :Angular آپلود فایل با/h2
    /div

    div ng-controller=ImageUploadMultipleCtrl

        div class=col-md-12 style=text-align:center;margin-bottom:10px;
            input type=file id=file name=file multiple onchange=angular.element(this).scope().setFile(this) accept=image/* class=btn btn-warning / 
        /div
        div class=col-md-12
            button ng-click=UploadFile() class=btn btn-primary آپلود/button
        /div
        
        div class=col-md-12 style=padding-top:10px;

                div class=col-md-7
                    table class=table table-bordered table-striped
                        thead
                            tr
                                thنام فایل/th
                                thنوع فایل/th
                                thسایز فایل/th
                                thوضعیت/th
                            /tr
                        /thead
                        tbody
                            tr ng-repeat=file in fileList

                                td{{file.file.name}}/td
                                td{{file.file.type}}/td
                                td{{file.file.size}}/td
                                td
                                    div id={{'P'+$index}}
                                        
                                    /div
                                /td

                            /tr
                        /tbody
                    /table
                /div
            /div
     /div
    !-- Loading JQuery--
    script src=~/App_Content/JS/jquery-1.7.2.min.js/script
    script src=~/App_Content/JS/jquery.unobtrusive-ajax.min.js/script
    !-- Lodaing the Angular JS--
    script src=~/App_Content/JS/angular.min.js/script
    
    !-- Load our Angular Application--
    script src=~/App_Content/JS/Practical/Module.js/script
    !-- Load the page Controller--
    script src=~/App_Content/JS/Practical/ImageUploadMultipleController.js/script
/body
/html
  1. ng-controller: “ImageUploadMultipleCtrl” کنترلر مربوط به این صفحه را مشخص می کند که شامل کدی برای نمایش اطلاعات فایل انتخاب شده و تابع آپلود فایل می باشد.
  2. <input type=”file” id=”file” name=”file” multiple

onchange=”angular.element(this).scope().setFile(this)”>

امکان وارد کردن چندین فایل را به ما می دهد. با رویداد onChange تابع setFile را فراخوانی می کنیم که یک تابع Angular است. این تابع همه فایل های انتخاب شده را جمع آوری کرده و در متغیر $scope به نام fileList می گذارد.

  1. به محض اینکه اطلاعات فایل در fileList ذخیره شد، با استفاده از کد <tr ng-repeat=”file in fileList”> حلقه ای روی fileList برای نمایش اطلاعات فایل اجرا می کنیم.
  2. هر فایل به طور خودکار سه ویژگی name، type و size دارد که به طور مستقیم می توان به آن دسترسی پیدا کرد.

حالا به سراغ controller رفته و تابع setFile را برای ایجاد fileList برنامه نویسی می کنیم. به محض ست کردن fileList  با فایل های انتخابی ما، Angular فورا اطلاعات فایل انتخاب شده را نمایش می دهد. این معجزه auto binding در Angular است.

ابتدا باید ماژول Angular را به صورت زیر در Module.js تعریف کنیم.

var app = angular.module('AgApp', [])

حال از این ماژول برای توسعه controller خود به منظور آپلود فایل استفاده می کنیم. کد زیر یک angular controller با تابع setFile می باشد. فایل ImageUploadMultipleController به صورت زیر است:

app.controller('ImageUploadMultipleCtrl', function ($scope) {

    $scope.fileList = [];
    $scope.curFile;
    $scope.ImageProperty = {
        file:''
    }

    $scope.setFile = function (element) {
        $scope.fileList = [];
       // get the files
        var files = element.files;
        for(var i=0;i&lt;files.length;i++)
        {
            $scope.ImageProperty.file = files[i];
            
            $scope.fileList.push($scope.ImageProperty);
            $scope.ImageProperty = {};
            $scope.$apply();
          
        }
    }

});

ImageUploadMultipleCtrl نام Controller ماست.

متغیر $scope به نام fileList یک آرایه از فایل های انتخاب شده می باشد.

گام اول در اینجا به پایان می رسد، پروژه را اجرا کرده و با استفاده از کلید Ctrl چندین فایل را انتخاب می کنیم و شکل زیر را مشاهده خواهیم کرد.

فراموش نکنید که Module.js و ImageUploadMultipleController.js را همانطور که در فایل HTML بالا نشان داده شد به انتهای صفحه اضافه می کنیم.

 آپلود در MVC

گام ۲: اضافه کردن امکان آپلود با استفاده از XMLHttpRequest

در این قسمت تابع آپلود خود را با استفاده از XMLHttpRequest توسعه می دهیم.

XMLHttpRequest یک API است که امکانات کلاینت را برای انتقال داده بین کلاینت و سرور را فراهم می کند.

این API یک روش ساده برای بازیابی داده ها از یک URL را بدون نیاز به refresh کامل صفحه فراهم می کند.

XMLHttpRequest به طور اورجینال توسط مایکروسافت طراحی شده است و با Mozilla، Apple و Google سازگار است.

برای اطلاعات بیشتر درباره XMLHttpRequest می توانید به آدرس زیر مراجعه نمایید:

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

ما به دلایل زیر XMLHttpRequest را انتخاب کردیم:

  1. امکان آپلود چندین فایل را به طور غیر همزمان به ما می دهد.
  2. امکان دنبال کردن پیشرفت آپلود هر فایل را به طور جداگانه به ما می دهد.

بعد از کامل کردن گام اول، ما همه فایل ها را در آرایه ای به نام fileList دریافت کردیم.

بنابراین حلقه ای روی fileList زده و هر فایل را به همراه name، type و size دریافت کرده و برای آپلود به تابع دیگری ارسال می کنیم.

بنابراین دو تابع به Controller خود در ImageUploadMultipleController.js اضافه می کنیم.

  1. ()UploadFile: این تابع زمانی که روی دکمه آپلود کلیک می کنیم، فراخوانی می شود.
  2. (fileToUpload,name,type,size,index)UplaodFileIndividual: این تابع وظیفه آپلود فایل ها را به صورت جداگانه دارد. این تابع ۴ پارامتر: فایل برای آپلود، نام فایل، نوع فایل، حجم فایل و اندیس آن را می گیرد.
$scope.UploadFile=function()
    {

        for (var i = 0; i  $scope.fileList.length; i++)
        {

            $scope.UploadFileIndividual($scope.fileList[i].file,
                                        $scope.fileList[i].file.name,
                                        $scope.fileList[i].file.type,
                                        $scope.fileList[i].file.size,
                                        i);
        }

    }

$scope.UploadFileIndividual = function (fileToUpload,name,type,size,index)
    {
        //Create XMLHttpRequest Object
        var reqObj = new XMLHttpRequest();

       //open the object and set method of call(get/post), url to call, isAsynchronous(true/False)
        reqObj.open(POST, /FileUpload/UploadFiles, true);

       //set Content-Type at request header.for file upload it's value must be multipart/form-data
        reqObj.setRequestHeader(Content-Type, multipart/form-data);

        //Set Other header like file name,size and type
        reqObj.setRequestHeader('X-File-Name', name);
        reqObj.setRequestHeader('X-File-Type', type);
        reqObj.setRequestHeader('X-File-Size', size);

        // send the file
        reqObj.send(fileToUpload);

    }

کدها برای توضیحات بیشتر کامنت گذاری شده است.

نتیجه این قسمت بدون برنامه نویسی ASP.Net MVC Controller جهت دریافت شی ارسال شده توسط XMLHttpRequest، قابل مشاهده نیست.

گام ۳: توسعه ASP.Net MVC Controller

حال باید ASP.Net MVC Controller را توسعه دهیم تا بتوانیم فایل ارسال شده از XMLHttpRequest را دریافت نماییم.

[HttpPost]
public virtual string UploadFiles(object obj)
{
    var length = Request.ContentLength;
    var bytes = new byte[length];
    Request.InputStream.Read(bytes, 0, length);

    var fileName = Request.Headers[X-File-Name];
    var fileSize = Request.Headers[X-File-Size];
    var fileType = Request.Headers[X-File-Type];

    var saveToFileLoc = \\\\adcyngctg\\HRMS\\Images\\ + fileName;

    // save the file.
    var fileStream = new FileStream(saveToFileLoc, FileMode.Create, FileAccess.ReadWrite);
    fileStream.Write(bytes, 0, length);
    fileStream.Close();

    return string.Format({0} bytes uploaded, bytes.Length);
}

حال اگر برنامه را اجرا کرده و بعد از انتخاب فایل روی دکمه آپلود کلیک کنیم، به سادگی تمام فایل های آپلودشده را خواهیم دید.

اما هیچ پیام یا اطلاعی از روند  پیشرفت آپلود نداریم.

اجازه بدهید که به مرحله بعد رفته و یک Event Handler برای شی XMLHttpRequest ایجاد نماییم.

گام ۴: بررسی روند پیشرفت هر یک از فایل ها به صورت جداگانه

شیء XMLHttpRequest وضعیت رویداد هر فایل را برمی گرداند.

با نوشتن یک تابع Event Handler می توانیم به این وضعیت دسترسی داشته باشیم.

در اینجا از متد addEventListener مربوط به شی XMLHttpRequest برای مدیریت رویداد استفاده می کنیم.

XMLHttpRequest در وضعیت های مختلف هنگام آپلود با رویداد های زیر مواجه می شود:

  1. Progress: در طول فرایند آپلود اتفاق می افتد و اطلاعات ضروری روند پیشرفت را برای ما ارسال می کند.
  2. load: زمانی اتفاق می افتد که فایل آپلود شده در مقصد ذخیره شده و سرور یک پاسخ برمی گرداند.
  3. error: به محض وقوع هر گونه خطا در طول آپلود، اتفاق می افتد.
  4. abort: به محض اینکه کاربر از فرایند آپلود انصراف می دهد، اتفاق می افتد.

برای مدیریت پیشرفت آپلود باید به شکل زیر عمل کنیم:


the following command catch the progress event and pass it to our own function named 
uploadProgress.
*/
reqObj.upload.addEventListener(progress, uploadProgress, false)

function uploadProgress(evt) {
            if (evt.lengthComputable) {
               
               var uploadProgressCount = Math.round(evt.loaded * 100 / evt.total);
           
               document.getElementById('P' + index).innerHTML = uploadProgressCount;

              // when upload complete then show a spiner icon till the server send back a response
               if(uploadProgressCount==100)
               {
                   document.getElementById('P' + index).innerHTML =

                  'i class=fa fa-refresh fa-spin style=color:maroon;/i';
               }
                
            }
        }

برای مدیریت کامل شدن بارگذاری باید به شکل زیر عمل کنیم:

reqObj.addEventListener(load, uploadComplete, false)


function uploadComplete(evt) {

            /* This event is raised when the server  back a response */

            document.getElementById('P' + index).innerHTML = 'Saved';

            $scope.NoOfFileSaved++;

            $scope.$apply();

        }
reqObj.addEventListener(error, uploadFailed, false)

function uploadFailed(evt) {

document.getElementById('P' + index).innerHTML = 'Upload Failed..';

}

برای مدیریت انصراف در حین آپلود از کد زیر استفاده می کنیم:

reqObj.addEventListener(abort, uploadCanceled, false)

function uploadCanceled(evt) {

document.getElementById('P' + index).innerHTML = 'Canceled....';

}

 

به این ترتیب Controller مربوط به آپلود آماده است. Controller نهایی به شکل زیر خواهد بود:

ImageUploadMultipleController.js

$scope.UploadFileIndividual = function (fileToUpload,name,type,size,index)

    {

        //Create XMLHttpRequest Object

        var reqObj = new XMLHttpRequest();

        //event Handler

        reqObj.upload.addEventListener("progress", uploadProgress, false)

        reqObj.addEventListener("load", uploadComplete, false)

        reqObj.addEventListener("error", uploadFailed, false)

        reqObj.addEventListener("abort", uploadCanceled, false)

       //open the object and set method of call(get/post), url to call, isasynchronous(true/False)

        reqObj.open("POST", "/FileUpload/UploadFiles", true);

       //set Content-Type at request header.For file upload it's value must be multipart/form-data

        reqObj.setRequestHeader("Content-Type", "multipart/form-data");


        //Set Other header like file name,size and type

        reqObj.setRequestHeader('X-File-Name', name);

        reqObj.setRequestHeader('X-File-Type', type);

        reqObj.setRequestHeader('X-File-Size', size);


        // send the file

        reqObj.send(fileToUpload);

        function uploadProgress(evt) {

            if (evt.lengthComputable) {


               var uploadProgressCount = Math.round(evt.loaded * 100 / evt.total);

               document.getElementById('P' + index).innerHTML = uploadProgressCount;


               if(uploadProgressCount==100)

               {

                   document.getElementById('P' + index).innerHTML =

</pre>
'i class="fa fa-refresh fa-spin" style="color:maroon;"/i';
<pre>
               }



            }

        }



        function uploadComplete(evt) {

            /* This event is raised when the server  back a response */


            document.getElementById('P' + index).innerHTML = 'Saved';

            $scope.NoOfFileSaved++;

            $scope.$apply();

        }



        function uploadFailed(evt) {

            document.getElementById('P' + index).innerHTML = 'Upload Failed..';

        }


        function uploadCanceled(evt) {



            document.getElementById('P' + index).innerHTML = 'Canceled....';

        }

    }

اگر برنامه را اجرا کنید، تصویر زیر را مشاهده خواهید کرد. (لطفا فایل web.config را همانطور که در گام ۵ توضیح داده شده، تغییر دهید.)

AngularJS

گام ۵: تغییر حداکثر طول آپلود در web.config

برای آپلود فایل های بزرگ باید حداکثر طول آپلود در web.config را تغییر دهیم.

در <system.web> قسمت http را به روش زیر تغییر می دهیم.


httpRuntime targetFramework=4.5maxRequestLength=1048576/

<system.webServer> را به شکل زیر آپدیت می کنیم و اگر وجود نداشت، آن را اضافه می کنیم.

system.webServer

    security

      requestFiltering

        requestLimits maxAllowedContentLength=1073741824 /

      /requestFiltering

توجه داشته باشید که مقدار maxRequestLenght در <system.web> و maxAllowedContentLenght در <system.webServer> باید یکی باشد.

 

جزئیات فایل

زبان پروژه : C#&MVC&JS
حجم فایل پیوست : 3 MB

دانلود فایل

دانلود با لینک مستقیم
پسورد فایل : www.mspsoft.com
فاطمه زکایی

فاطمه زکایی هستم. فارغ التحصیل کارشناسی مهندسی نرم افزار، مدت سه سال هست که در زمینه توسعه اپلیکیشن های تحت وب و اندروید و همچنین تولید محتوای تخصصی برنامه نویسی تحت وب و اندروید در مجموعه mspsoft در خدمت شما هستم.

نوشته‌های مرتبط

دیدگاه‌ها

*
*

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.

    مسعود پاسخ

    سلام دمتون گرم
    عالی بود
    ممننون

    حسن پاسخ

    سلام.
    پیام تابع ()uploadComplete چه زمانی چاپ میشه؟
    نوشتین که در هنگام ذخیره فایل در مقصد.
    مقصد کجاست؟ روی هارد سرور یا روی دیتابیس؟

      مسعود شریفی پاسخ

      روی سرور به صورت فیزیکی.

    حسن پاسخ

    سوال دومم اینه که درتوضیح ()uploadComplete نوشتین زمانی اتفاق می افتد که فایل آپلود شده در مقصد ذخیره شده و سرور یک پاسخ برمی گرداند.
    پاسخی که سرور برمیگردونه کجاست؟ متد load() از کجا این پاسخو دریافت میکنه؟