آپلود فایل ها با استفاده از PlUpload در Asp.Net Mvc
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: چهار دقیقه

امروزه بازار برنامه‌های تماما ajax و بدون Postback  شدن صفحه بسیار داغ میباشد که از این موارد میتوان به برنامه‌های تحت وب گوگل اشاره کرد. (gmail  ، googlePlus  ، Google Reader)
در این میان یکی از دغدغه‌های توسعه دهندگان وب ، آپلود فایل‌ها به صورت آنی (مثل attach files گوگل) میباشد. برای حل این مسئله ، ابزارها و پلاگین‌های متعددی وجود دارد که در اینجا به 10 تا از پلاگین‌های Jquery  اشاره شده است.
به شخصه با پلاگین Uploadify کار کرده ام و از استفاده از آن راضی هستم ولی همین دیشب برای قسمتی از یک پروژه نیاز
به ابزاری جهت آپلود فایل‌ها با امکانات مورد نظرم داشتم که به PlUpload برخورد کردم. 

از امکاناتی که این ابزار در اختیار شما قرار میدهد :
- یک اینترفیس زیبا جهت آپلود و افزودن فایل ها
- پشتیبانی از زبان‌های مختلف و همین طور زبان فارسی
- امکان استفاده از قالب Jquery UI
- Drag&Drop  برای مرورگرهایی که از Html5  پشتیبانی میکنند

حال که با امکانات این ابزار بیشتر آشنا شدید بریم سراغ استفاده از این ابزار در asp.net mvc  :)
ابتدا پروژه را از اینجا دانلود کنید. سپس یک پروژه‌ی جدید  mvc 3  بسازید (از نوع Internet Application و با نام دلخواه). سپس پوشه‌ی plupload  را در قسمت سلوشن برنامه کپی کنید.
حال در فایل Views->Shared->_Layout.cshtml  ، تگ head  را جهت افزودن امکانات پلاگین این گونه تغییر دهید :

    <title>@ViewBag.Title</title>

    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <link href="../../plupload/js/jquery.plupload.queue/css/jquery.plupload.queue.css" rel="stylesheet" />
    <script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
    <script type="text/javascript" src="http://bp.yahooapis.com/2.4.21/browserplus-min.js"></script>

    <script src="../../plupload/js/plupload.full.js"></script>
    <script src="../../plupload/js/jquery.plupload.queue/jquery.plupload.queue.js"></script>
    <script src="../../plupload/js/i18n/fa.js"></script>

نکته : فایل fa.js  که جهت استفاده از زبان فارسی در اینترفیس آپلود فایل‌ها میباشد، که وجود آن در آدرس واضح میباشد.
سپس به فایل Views->Home->Index.cshtml بروید و آن را این گونه دوباره نویسی کنید :
 @{
    ViewBag.Title = "Uploading Files using PlUpload";
}
<h2>@ViewBag.Message</h2>

@using (Html.BeginForm("Post", "home", FormMethod.Post,
    new { enctype = "multipart/form-data" }))
{
    <div id="uploader">
        <p>You browser doesn't have Flash, Silverlight, Gears, BrowserPlus or HTML5 support.</p>
    </div>
}

<script>
    $(function () {

        $("#uploader").pluploadQueue({
            // General settings
            runtimes: 'html5,gears,flash,silverlight,browserplus,html4',
            url: '@Url.Action("Upload" , "Home")',
            max_file_size: '10mb',
            chunk_size: '1mb',
            unique_names: true,

            // Resize images on clientside if we can
            resize: { width: 320, height: 240, quality: 90 },

            // Specify what files to browse for
            filters: [
                { title: "Image files", extensions: "jpg,gif,png" },
                { title: "Zip files", extensions: "zip" }
            ],

            // Flash settings
            flash_swf_url: '/plupload/js/plupload.flash.swf',

            // Silverlight settings
            silverlight_xap_url: '/plupload/js/plupload.silverlight.xap'
        });
    });
</script>
توضیحات و نکات :
- جهت آپلود فایل‌ها تگ enctype = "multipart/form-data" را فراموش نکنید.
- در قسمت مقداردهی به ویژگی‌های Plupload  ، قسمت runtime  به صورت ترتیبی کار میکند لذا اگر اولی پشتیبانی نشود سراغ دومی میرود و اگر دومی نشود سومی و ... در صفحه‌ی اول سایت PlUpload ، موارد پشتیبانی شده توسط تکنولوژی‌ها آورده شده است لذا این ترتیب را ترتیب مناسبی میبینم و اگر اولین مورد html5 باشد امکان Drag&Drop وجود خواهد داشت.
خود سایت PlUpload  داکیومنت خیلی خوبی جهت توضیح موارد مختلف دارد لذا توضیح دوباره لازم نیست.
همان طور که در ویژگی url  مشاهده میکنید به کنترلر Home  و اکشن متود Upload اشاره شده است که طرز کار به این گونه است که هر بار که یک فایل آپلود میشود درخواستی به این آدرس و محتوای فایل در قسمت Request.Files ارسال میشود و همین طور نام فایل که unique ارسال میشود و chunk که تیکه‌های فایل است(پست میشود).
پس اکشنی با نام Upload  در کنترلر HomeController بسازید :
        [HttpPost]
        public ActionResult Upload(int? chunk, string name)
        {
            var fileUpload = Request.Files[0];
            var uploadPath = Server.MapPath("~/App_Data");
            chunk = chunk ?? 0;
            using (var fs = new FileStream(Path.Combine(uploadPath, name), chunk == 0 ? FileMode.Create : FileMode.Append))
            {
                if (fileUpload != null)
                {
                    var buffer = new byte[fileUpload.InputStream.Length];
                    fileUpload.InputStream.Read(buffer, 0, buffer.Length);
                    fs.Write(buffer, 0, buffer.Length);
                }
            }
            return Content("chunk uploaded", "text/plain");
        } 
توضیحات : ابتدا فایل مورد نظر از قسمت Request.Files واکشی میشود و سپس فایل را در پوشه App_Data ذخیره میکند. (یکی از چندین روش ذخیره سازی که مطالعه در این قسمت به خواننده واگذار میشود.)

حال برنامه را اجرا کنید و از این ابزار لذت ببرید:) 
نکته : قسمت فارسی ساز اونو تغییر دادم چون که ترجمه‌ی فارسی خودش یه سری نقایصی داشت که گویا از کار با google translate به وجود اومده بود!
  • #
    ‫۱۲ سال و ۱ ماه قبل، دوشنبه ۶ شهریور ۱۳۹۱، ساعت ۲۰:۵۶
    سلام
    همه این ابزار‌ها برای ارسال فایل به سرور از فلش استفاده می‌کنند.
    و یه طورایی نمی‌شه گفت این کار با ای جکس انجام شده (ولی می‌شه گفت بدون پست بک)
    موفق باشید.
    • #
      ‫۱۲ سال و ۱ ماه قبل، دوشنبه ۶ شهریور ۱۳۹۱، ساعت ۲۱:۵۷
      فلاش یکی از روش هاس ... ولی در کل حرف شما درسته و من به همین خاطر از واژه‌ی "  آپلود فایل‌ها به صورت آنی " استفاده کردم
      • #
        ‫۱۲ سال و ۱ ماه قبل، سه‌شنبه ۷ شهریور ۱۳۹۱، ساعت ۰۲:۳۹
        ممنون از آموزش شما.

        من خودم  از این پلاگین استفاده می‌کنم.پلاگینی برای jquery هست و بدون استفاده از فلش و خیلی راحت با استفاده از ajax فایل را آپلود می‌کنه.

        بازم ممنون
  • #
    ‫۱۱ سال و ۸ ماه قبل، جمعه ۲۷ بهمن ۱۳۹۱، ساعت ۰۵:۱۴
    تشکر بابت مطلب کاربردیتون
    فقط یک مشکل داره اونم وقتی هست که فایل‌ها upload شدن . دیگه اجازه‌ی ulpoad دوباره نمیده

  • #
    ‫۱۱ سال و ۶ ماه قبل، شنبه ۳ فروردین ۱۳۹۲، ساعت ۰۲:۱۶
    سلام 
    من یک فایل آپلودر خیلی جمع و جور میخوام که فقط یک فایل رو آپلود کنه ولی ایجکسی باشه / اگه لطف کنین راهنمایی کنین که چطوری میتونم فایل آپلود رو در MVC بتونم به صورت ajax همراه با loading  داشته باشم ممنون میشم .
  • #
    ‫۱۱ سال و ۵ ماه قبل، شنبه ۱۴ اردیبهشت ۱۳۹۲، ساعت ۱۷:۴۲
    سلام
    چطور میشه از لیست اسامی فایل‌های ارسال شده، در هنگام ثبت اطلاعات مدل در سرور استفاده کرد؟
    در واقع اطلاعات فایل ها، قسمتی از اطلاعات مدل من محسوب میشه و در هنگام ثبت در دیتابیس باید این لیست رو هم ثبت کنم. ولی نمیدونم چطور در کنترلر ثبت مدل به اسامی فایلها دسترسی داشته باشم. 
    مثلا مدل زیر :
    public class album
    {
    public string  name;
    public string des;
    public string[] images;
    }
    من اطلاعات مدل  رو در حالت آجاکس به صورت ajax.beginform  ارسال میکنم. 
    ممنون میشم اگر دوستان پاسخ بدن
    • #
      ‫۱۱ سال و ۵ ماه قبل، شنبه ۱۴ اردیبهشت ۱۳۹۲، ساعت ۱۸:۲۳
      در متد public ActionResult Upload بالا fileUpload.FileName اسم واقعی فایل هست؛ پارامتر name یک اسم موقتی.
      • #
        ‫۱۱ سال و ۵ ماه قبل، شنبه ۱۴ اردیبهشت ۱۳۹۲، ساعت ۱۸:۴۶
        خیلی ممنون از پاسختون
        این قسمتی رو که گفتین درسته. من مرحله بعد از این رو مشکل دارم. 
        سوال اینه:
        بعد از ارسال فایل‌ها به سرور، حالا نوبت ارسال اطلاعات مدل به سرور می‌رسه که این اسامی فایل‌ها هم قسمتی از اطلاعات مدل هست. چطور می‌شود در اکشن ثبت مدل، اسامی فایل‌ها اپلود شده را دریافت کرد و استفاده نمود.
        یه راه حلی پیدا کردم که گفته بود بعد از اینکه کار آپلودر تموم شد اطلاعات فایل‌ها را به صورت فیلد مخفی در فرم ذخیره کن تا پست بک شود. نمیدونم آیا راه حل دیگه ای هست؟ این روش درست و اصولیه؟
        uploader.bind('FileUploaded', function(up, file, info) {
          var obj = JSON.parse(info.response);
            $('form#quoteRequest').append('<input type="hidden" name="file_name" value="' + obj.result.cleanFileName + '" />');
            //note obj.result.cleanFileName instead obj.cleanFileName
         });

        • #
          ‫۱۱ سال و ۵ ماه قبل، شنبه ۱۴ اردیبهشت ۱۳۹۲، ساعت ۱۹:۰۰
          // JS
          up.settings.multipart_params = {
                              description: $("#imageDescription").val(),
                              // other fields ....                  
                          };
          // C#
          string description = context.Request.Form["description"];
          باید از multipart_params تنظیمات این افزونه برای ارسال اطلاعات اضافی استفاده کنید.
          • #
            ‫۱۱ سال و ۵ ماه قبل، شنبه ۱۴ اردیبهشت ۱۳۹۲، ساعت ۱۹:۱۳
            با تشکر از دوستان .
            یک مثال عملی؛ یه نرم افزار ارسال ایمیل تحت وب مثل جیمیل رو در نظر بگیرید. یه فرم ارسال ایمیل داره که می‌خواد اطلاعات رو بفرسته به سمت سرور. یه سری فایل هم قراره بصورت آجاکسی پیوست بشه. مراحل کار بدین صورته که ابتدا فایل‌ها آجاکسی به سرور فرستاده می‌شوند و یه جایی ذخیره می‌شوند. بعد فرم اطلاعات شامل گیرنده ، متن نامه و غیره بصورت آجاکس ارسال میشه. وقتی در سمت سرور می‌خوایم ایمیل رو بفرستیم، نیاز داریم که نام فایل‌های پیوست  شده در مرحله قبل رو هم داشته باشیم. 
            همونطور که قبلا خدمت دوستان عرض کردم؛ راه حلی که من بذهنم می‌رسه اینه که بعد از اینکه فایل‌ها در مرحله اول آپلود شد، اسم فایل‌ها رو توی فرم در فیلد مخفی تزریق کنیم. بعد که فرم پست شد، طبیعتا دسترسی به نام فایل‌ها داریم. کد ذکر شده هم کار تزریق در هنگام تمام شدن ارسال فایل‌ها انجام میداد.
            خواستم بدونم آیا این روش درست هست؟ و آیا روش تمیزتری وجود داره؟
            باز هم تشکر
            • #
              ‫۱۱ سال و ۵ ماه قبل، شنبه ۱۴ اردیبهشت ۱۳۹۲، ساعت ۱۹:۲۶
              همان روشی که برای دریافت نام فایل‌های آپلود شده از سرور انتخاب کردید، مناسب است:
              $("#uploader").pluploadQueue({
                    // Post init events, bound after the internal events
                    init: {
                             FileUploaded: function(up, file, info) {
                             // Called when a file has finished uploading
                             } 
                    }
              });
    • #
      ‫۱۱ سال و ۵ ماه قبل، شنبه ۱۴ اردیبهشت ۱۳۹۲، ساعت ۱۸:۴۶
      اینکار توصیه نمیشه. چون پس از اطمینان کامل از آپلود یک فایل باید نسبت به ذخیره اطلاعات آن اقدام کنید. الزامی نداره که ارسال فرم حتما به آپلود موفقیت آمیز فایل‌ها در این حالت خاص منجر بشه (چون مثلا از فلش یا سیلورلایت مجزای از فرم شما هم ممکن است برای ارسال داده‌های فایل‌ها استفاده کنه). یعنی آپلود فایل در اینجا بحث مجزایی از فرم شما است. ابتدا فایل‌ها را آپلود کنید؛ بعد اجازه بدید تا توضیحات مرتبط را ثبت کنند.
      یا اینکه می‌شود در حین آپلود توسط افزونه هم یک سری توضیحات اضافی رو ارسال کرد:
      // JS
      up.settings.multipart_params = {
                          description: $("#imageDescription").val()                   
                      };
      // C#
      string description = context.Request.Form["description"];
  • #
    ‫۱۱ سال و ۱ ماه قبل، جمعه ۱۵ شهریور ۱۳۹۲، ساعت ۱۴:۰۶
    ممنون از مطالب که گفتین. فقط سایتش دیگه اجازه دانلود نمیده، آیا از جایی دیگه میتونم بگیرم؟ و دوم اینکه mvc 4 رو هم ساپورت میکنه یا نه؟ مرسی
    • #
      ‫۱۱ سال و ۱ ماه قبل، جمعه ۱۵ شهریور ۱۳۹۲، ساعت ۱۴:۵۰
      plupload سورس باز هست . البته با مجوز GPL. یعنی کار خودتون رو باید سورس باز کنید (یا مجوزش رو بخرید). ضمنا MVC4 با MVC3 سازگار هست. فقط یک سری افزونه بیشتر داره.
  • #
    ‫۱۰ سال و ۴ ماه قبل، چهارشنبه ۲۱ خرداد ۱۳۹۳، ساعت ۱۳:۳۱
    باسلام. من این کارهایی که گفتید کردم. روی vs مشکلی نداشتم. ولی وقتی نرم افزارمو پابلیش کردم و روی سرور گذاشتم متأسفانه هرکار می‌کنم خطا عدم پشتیبانی مرورگر میده. با فایرباگ چک کردم دیدم به فایلهای کتابخانه اش عدم دسترسی می‌ده. تمام تنظیمات iis رو هم چک کردم. نتونستم درستش کنم.
    خطایی که میده اینطوریه:
    NetworkError: 404 Not Found - http://~/Scripts/plupload/js/jquery.ui.plupload/jquery.ui.plupload.js" 
  • #
    ‫۱۰ سال و ۲ ماه قبل، دوشنبه ۶ مرداد ۱۳۹۳، ساعت ۱۳:۳۴
    سلام
    یه سوال؟  وقتی بخوایم اطلاعات ذخیره شده (فایلی که قبلا آپلود کرده) رو نمایش بدیم چجوری فایل رو توی plUpload نمایش بدیم؟ خود سایت FilesAdded داره که کار نمیکنه.