نظرات اشتراک‌ها
پیش نمایش Rider 2019.1
من این ide رو نصب کردم و از آن هرازگاهی استفاده میکنم، چندتا از ویزگیهاش(هم مثبت و هم منفی) که الان به ذهنم می‌رسه رو عرض می‌کنم:
1- توی لود پروژه هایی که تعداد فایل زیادی دارند خیلی کند هست. الان مدتی هست که روی یک پروژه روی asp.net mvc core 2 کار می‌کنم، تعداد فایلهای آن ذاتاً زیاد است، و چندتا پروژه اوپن سورس هم که بهش اضافه کردم تعداد فایل بیشتر هم شده و rider واقعاً در بحث لود کردن و ایندکسینگ بسیار کند عمل میکنه.(البته اگر هارد ssd داشته باشید فکر نکنم مشکلی باشه)
2- برای کسی که سالها با visual studio کار کرده برقراری ارتباط با آن کمی مشکل هست، مخصوصاً در بحث go to definition و ...
3-حتماً باید ram سیستم در حد مطلوب باشد، درسته حجم خود نرم افزار نسبت به vs بسیار کمه اما در زمان اجرا واقعاً رم بسیار زیادی می‌گیره.
4- گاهی خطاهایی در زمان debug میگیره که در visual studio اتفاق نمیافته
5- چون resharper رو ذاتاً در خودش داره توی refactoring و بهینه کردن کدها بسیار کمک میکنه.
6- بنده توی خطایابی و رفع خطاهای موجود در کدها در visual studio راحت‌تر هستم، مخصوصاً بعد از نصب ابزارهای roslyn به نظرم visual studio راحت‌تر عمل میکنه.
7- واقعاً find در visual studio نسبت به find این ide حرفی برای گفتن نداره، البته بنده گاهی که نیاز به جستجوی سریع و پیچیده دارم از هیچکدوم استفاده نمیکنم در این مواقع از sublime text استفاده میکنم
8- در زمینه کار با سیستمهای version control به نظرم هردو امکانات خوب و کاملی دارند، منتها به سبب عادت من با visual studio راحت ترم.
9- با همه اینها فکر میکنم اگر عادت کنیم rider یک ide قابل تحسینیه، و با بهبودهایی که خواهد داشت مطمئنا برای dotnet core یک ide پرطرفداری خواهد بود
نظرات مطالب
استخراج متن از فایل‌های PDF توسط iTextSharp
برای استخراج متن و عکس و رندر کردن می‌تونید از این کتابخانه PdfLib.Net  با چند خط کد، متن کامل فارسی رو بدون مشکل استخراج کنید. البته حجم این کتابخونه یکم زیاده چون کار اصلیش رندر کردن PDF.
PDFLibNet.PDFWrapper wrapper = new PDFLibNet.PDFWrapper();
            wrapper.LoadPDF(pdfPath);
            string page1Text = wrapper.Pages[1].Text;
نظرات مطالب
C# 8.0 - پیشنیاز و روش راه اندازی
پس از ارائه‌ی NET Core 3.0 Preview 7.، اگر <TargetFramework>netcoreapp3.0</TargetFramework> باشد، یعنی در حال استفاده‌ی از C# 8.0 هستید. همچنین پس از ارائه‌ی Preview 8، اگر TargetFramework کتابخانه‌ای به netstandard2.1 تنظیم شود نیز به همین معنا است و نیاز به تنظیمات اضافه‌تری ندارد.
مطالب
Best practiceهای یک پروژه Blazor
Blazor، چارچوبی است ارائه شده توسط مایکروسافت که به ما اجازه می‌دهد برنامه‌های تعاملی وب را با CSharp و بدون JavaScript بنویسیم. ‌Blazor از اساس، Component based بوده و در برنامه‌هایی که Backend نیز با CSharp نوشته شده باشد ( مثلا با ASP.NET Core) امکان به اشتراک گذاری کد بین کلاینت و سرور را نیز فراهم می‌کند. معماری Blazor معماری‌ای مدرن است که در دل خود از امکانات CSharp نیز به خوبی بهره برده است تا بتوان پروژه را به‌صورتی که قابلیت نگهداری بالایی داشته باشد، توسعه داد. Blazor در ذات معماری خود امکان نوشتن برنامه‌های Native موبایل را نیز می‌دهد و برای اثبات این مهم چندین دمو برای Proof of concept ارائه شده است؛ اما تا به امروز امکانی که به صورت Production ready باشد، ارائه نشده است.
Blazor به دو شکل کار می‌کند. Blazor Server و Blazor Client
در Blazor Client با استفاده از پشتیبانی نزدیک به 90% ای مرورگرها از Web Assembly که اجازه اجرای کدهای غیر JavaScript ای را در مرورگر می‌دهد، ابتدا DLLها به همراه HTML-CSS و عکس‌ها و ... دانلود شده و برنامه به صورت Single Page App کار می‌کند. در این مدل شما می‌توانید از تکنیک Pre rendering یا SSR نیز استفاده کنید تا تجربه کاربری بهتری را نیز ارائه دهید و یا در بحث SEO بهتر عمل کنید.
‌Blazor در سمت کلاینت از NET Standard 2.1 پشتیبانی می‌کند که عملا به شما اجازه می‌دهد بازه‌ی گسترده‌ای از Nuget Packageها را استفاده کنید.

البته Blazor Client به صورت Preview ارائه شده است و "فعلا" دو مشکل را دارد:
۱- امکان دیباگ خوبی ندارد.
۲- در عمل باید فایل‌های اجرایی برنامه به صورت wasm یا web assembly دانلود شوند که در این حالت سرعتی بسیار بالا و بیش از جاوااسکریپت خواهند داشت؛ اما تا این لحظه این فایلها به صورت DLL دانلود میشوند و در سمت مرورگر "تفسیر" میشوند که باعث میشود سرعت گاه تا 70 برابر کمتر شود.
البته این دو مشکل در زمان ارائه نسخه NET 5. حل خواهند شد و در پروژه نسخه نهایی خود این دو مشکل را نخواهد داشت.

Blazor مدل اجرای دومی نیز دارد که به آن Blazor Server نیز می‌گوییم. در این مدل کدها تماما سمت سرور اجرا می‌شوند و تعاملات UI به صورت Web Socket به کلاینت منتقل و یا از آن دریافت می‌شوند که در این مدل، امکان Debug بدون کوچک‌ترین مشکلی کار می‌کند و مشکلی از بابت کندی دانلود و اجرای DLLها ندارد. فقط چون کدها تماما سمت سرور اجرا می‌شوند، در زمانیکه ارتباط شبکه‌ای، مناسب نباشد، می‌توانیم در سناریوهای مختلف، شاهد لگ و کندی باشیم.

آینده‌ی Blazor در مدل اول آن تعریف شده‌است و در گذر زمان برای مدل Blazor Server، نمیتوان آینده‌ی زیادی را متصور بود. اما نکته‌ی مهم و جالب اینجاست که کد پروژه در هر دو مدل یکی است و فقط Configuration این دو از هم متفاوت است. پس اگر علاقمند به شروع به استفاده از Blazor هستید، یک راه این است که با مدل Blazor Server شروع و بعدا با تغییر Configuration، به Blazor Client سوئیچ کنید. البته در این میان باید به نکاتی دقت کنید:
۱- Blazor Server از NET Core 3.1. پشتیبانی می‌کند و Blazor Client از NET Standard 2.1. در مواقعی خاص ممکن است یک کلاس یا یک متد در NET Core 3.1. باشد و در NET Standard 2.1. نباشد.
۲- در Blazor Server شما حتی می‌توانید با Entity Framework Core مثلا به Sql Server وصل شوید؛ ولی طبیعتا Browser امکان اتصال مستقیم به Sql Server را در مدل Client به شما نخواهد داد.
این موارد باعث می‌شود که اگر پروژه را با Blazor Server شروع کنید، شاید در آن کارهایی را انجام دهید که در BlazorServer کار می‌کنند، ولی در BlazorClient کار نمی‌کنند و این باعث شود بعدا که نسخه نهایی و کامل BlazorClient آماده شد، شاید نتوانید به آن، به صورت ساده و آسانی سوئیچ کنید.

ایده آل این است که پروژه‌ای داشته باشید که به سادگی عوض کردن یک کلمه، بین این دو مدل سوئیچ کنید و بر صحت عملکرد پروژه در هر دو حالت نظارت داشته باشید. برای رسیدن به این مهم، پروژه‌ای را ساخته‌ام به نام BlazorDualMode که عمده‌ی بررسی‌ها را به صورت اتوماتیک انجام می‌دهد و عملا تضمینی بر مهاجرت آسان شما از BlazorServer به BlazorClient در آینده خواهد بود
اگر در نت جستجو کنید، پروژه‌هایی با این اسم را خواهید دید؛ اما این پروژه دو مزیت مهم را دارد که الباقی فاقد آن هستند:
۱- مدل Blazor Client آن دارای تکنیک Pre rendering یا SSR است.
۲- پروژه Api آن، از پروژه‌ی Blazor آن جداست. اگر پروژه‌ی Api را پروژه‌ای بدانیم که به همراه Model‌، Data و ... امکان دسترسی به DbContext و دیتابیس را دارد، جدا بودن پروژه‌ی Blazor باعث می‌شود که حتی در مدل Server آن نیز مجبور باشیم دیتا را از Api به صورت Rest Api call بگیریم و به واسطه پروژه Shared مابین Api و Blazor نهایت Dto‌ها و سایر کدهای مشترک را ببینیم.
البته در پروژه DualMode فقط پروژه Api درست شده‌است و ما کاری با جزئیات آن، اینکه مثلا CQRS می‌خواهیم یا نه، آیا میخواهیم لایه‌ای کار کنیم و ... نداریم و فقط روی موارد مرتبط با Blazor متمرکز شده‌ایم.
در پروژه یک فایل داریم به نام Directory.build.props. زمانیکه چنین فایلی در فولدری قرار بگیرد، تمامی موارد نوشته شده در آن به صورت ضمنی در تمامی فایل‌های csproj زیر مجموعه آن اعمال می‌شود.
در این فایل داریم:
<Project>
  <PropertyGroup>
    <BlazorMode>Client</BlazorMode>
    <DefineConstants Condition=" '$(BlazorMode)' == 'Client' ">$(DefineConstants);BlazorClient</DefineConstants>
    <DefineConstants Condition=" '$(BlazorMode)' == 'Server' ">$(DefineConstants);BlazorServer</DefineConstants>
    <LangVersion>8.0</LangVersion>
  </PropertyGroup>
</Project>
ابتدا یک متغیر را تعریف کرده‌ایم، به نام BlazorMode که می‌تواند یا Server باشدو یا Client، که فعلا Client است و به راحتی می‌توانید آن‌را عوض کنید.
در ادامه Define Constant کرده‌ایم که اجازه می‌دهد کدهای CSharp دخیل در Configuration پروژه Blazor را شرطی کنیم. برای مثال بنویسیم:
#if BlazorClient
...
#elif BlazorServer
...
#endif
این if‌ها که با # شروع می‌شوند، در هنگام Compile چک می‌شوند و کدی که در شرط با نتیجه true قرار بگیرد، Compile میشود و در خروجی برنامه قرار می‌گیرد و کدی که در شرط با نتیجه false قرار بگیرد، از اساس Compile نمیشود.
نسخه CSharp تمامی پروژه‌ها نیز 8.0 قرار داده شده است.

پروژه‌ی BlazorDualMode.Api آن پروژه‌ای است که Api Controllerها در آن قرار می‌گیرند و همچنین در حالت Blazor Client، پروژه را برای مرورگرها ارائه یا Serve می‌کند. به واقع در این مدل، درخواستی که به هیچ Api Controller ای نرسد، به Blazor تحویل میشود. Blazor نیز ابتدا به دنبال Component ای می‌گردد که برای Route مربوطه نوشته شده باشد و آن را اجرا می‌کند و سپس Response آماده، به کلاینت ارسال می‌شود. در ادامه، مرورگر فایل‌های DLL را دانلود و برنامه به صورت Single Page App به کار خود ادامه می‌دهد.
پروژه BlazorDualMode.Shared  پروژه‌ای است که کد مشترک بین Api و Blazor در آن قرار می‌گیرد. برای مثال میتوانید Dtoها را در این قسمت قرار دهید.
پروژه BlazorDualMode.Web پروژه‌ای است که در آن Component‌های Blazor قرار دارند. در حالت Server این پروژه نیز قابلیت اجرا می‌یابد و باید با امکانات Visual Studio یا IDE دلخواه خود پروژه Web و Api را به صورت همزمان اجرا کنید تا به درستی کار کند.

فایلهای Program.cs، Startup.cs و همچنین خود csproj‌ها و در نهایت فایل Host.cshtml، نهایت تفاوت این دو حالت بوده و کدهای بیزینسی پروژه و حتی Componentها و Api Controllerها در هر دو حالت یکی هستند. Configuration با شرط if server یا if client هندل شده‌اند و درک جزئیات تنظیمات مربوطه نیاز به تسلط بر روی خود Blazor را دارد که از موضوع این پست خارج است؛ ولی در صورت داشتن هر گونه سوالی، می‌توانید از قسمت پرسش و پاسخ همین سایت استفاده کنید.
مطالب
بررسی چند کتابخانه آپلود با پشتیبانی از DragDrop
برای یکی از پروژه‌ها نیاز به یک آپلودر داشتم که قابلیت  Drag&Drop را نیز داشته باشد و در ضمن پیاده سازی آسانی هم داشته باشد. در این بین به تعدادی از کتابخانه‌های جی کوئری می‌پردازیم.
FileDrop
اولین کتابخانه‌ای که با آن آشنا شدم و از آن استفاده کردم، کتابخانه‌ی FileDrop است که بسیار ساده و در عین حال قابلیت‌های خوبی را می‌دهد و از فناوری Filereader  (+) در Html5 برای اینکار استفاده می‌کند. مرورگرهای کروم، فایرفاکس 3.6 به بعد، IE10 به بعد و Opera 12 به بعد از آن پشتیبانی می‌کنند.
فایل‌های مورد نیاز را از اینجا دانلود کنید . فایل اسکریت آن را ابتدا صدا بزنید:
 <script src="~/scripts/jquery.filedrop.js" type="text/javascript"></script>
سپس المان‌های زیر را به کد HTML خود اضافه کنید:
 <div id="dropZone">فایل برنامه را به داخل این کادر بکشانید</div>
        <br>
        فایل یا فایل‌های آپلود شده:
        <ul id="uploadResult"></ul>
تگ اول، محلی است که فایل‌ها به سمت آن درگ و روی آن دراپ می‌شوند که از این به بعد به آن محل آپلود می‌گوییم. المان بعدی جهت گزارش فایل‌هایی است که آپلود شده‌اند. با آپلود شدن هر تعداد فایل، اسم آن به لیست اضافه می‌گردد.
کدهای css زیر را هم به صفحه اضافه کنید تا محل آپلود زیباتر شود:
        .files {
            min-height: 42px;
            background: #CCC none repeat scroll 0% 0%;
            border-top: 1px solid #FFF;
            margin: 11px 0px;
            padding: 11px 13px;
            border-radius: 6px;
        }

        #dropZone.mouse-over {
            background-color: #1d4257;
        }

کد جی کوئری زیر را به صفحه اضافه کنید:
      $('#dropZone').filedrop({
                url: uploadAddress,
                paramname: 'files',
                maxFiles: 1,
                dragOver: function() {
                    $('#dropZone').addClass('mouse-over');
                },
                dragLeave: function() {
                    $('#dropZone').removeClass('mouse-over');
                },
                drop: function() {
                    $('#dropZone').removeClass('mouse-over');
                },
                afterAll: function() {
                    $('#dropZone').html('آپلود با موفقیت انجام شد');
                },
                uploadFinished: function(i, file, response, time) {
                    $('#uploadResult').append('<li>' + file.name + '</li>');
                }
            });
ابتدا پلاگین جی کوئری را روی تگ مربوطه اعمال می‌کنیم و سپس پارامترها را با مشخصات زیر اعمال می‌کنیم:
Url  آدرسی که قرار است فایل‌ها به آن سمت ارسال شوند. 
 Paramname  در سمت سرور باید فایل‌ها را با استفاده از این نام پارامتر دریافت  کنید.
 maxFiles  تعداد فایلهایی که میتوان با درگ و دراپ کردن روی آن به دست آورد. در بالا به یک فایل محدود شده است.
 dragOver  این رویداد زمانی اجرا خواهد شد که اشاره گر با حالت درگ کرده فایل‌ها را به محل آپلود آورده است.
 dragLeave  موقعی که ماوس از محل آپلود خارج می‌شود
 drop  موقعی که شما فایل‌ها را روی محل  آپلود رها می‌کنید.
 afterAll  بعد از اینکه همه کارها تمام شد اجرا می‌شود.(آخرین رویداد)
 uploadFinished  کار آپلود به پایان رسیده است. در مثال بالا پس از پایان آپلود، نام فایل آپلود شده را به کاربر نشان داده‌ایم.

نحوه‌ی دریافت آن در سمت سرور, در یک اکشن متد به صورت زیر است:

[HttpPost]
        public virtual ActionResult UpdateApp(IEnumerable<HttpPostedFileBase>files)
        {
            foreach (HttpPostedFileBase file in files)
            {
                string filePath = Path.Combine(TempPath, file.FileName);
                file.SaveAs(filePath);
            }

            return Json(new {state = "success", message = "با موفقیت عملیات ارسال فایل انجام شد"}, JsonRequestBehavior.AllowGet);
        }

در اکشن متد بالا ما فایل‌ها را از طریق نام پارامتر files که مشخص کرده بودیم، به عنوان یک لیست شمارشی دریافت می‌کنیم.  کدها بالا برای ساده‌ترین راه اندازی ممکن کفایت می‌کنند.

این موارد از اصلی‌ترین‌ها هستند که به کار می‌آیند. به غیر این‌ها یک سری خصوصیات اضافه‌تری هم برای آن وجود دارد.


fallback_id 
 اگر دوست دارید این آپلودر را نیر به یک آپلودر معمولی اتصال دهید از این شناسه استفاده کنید.
 withCredentials   با استفاده از کوکی‌ها یک درخواست cross-origin ایجاد می‌کند.
 data  اگر دوست دارید به همراه فایل‌ها اطلاعات دیگری هم به همراه آن ارسال و پست شوند از این طریق اقدام نمایید. می‌تواند در قالب یک متغیر باشد یا خروجی یک تابع.
data: {
        param1: 'value1',           
        param2: function(){
            return calculated_data; 
        }
 headers برای ارسال مقدار اضافه‌تر در هدر درخواست به کار میرود و صدا زدن آن همانند کد data می‌باشد. 
 error   در صورتیکه در فرایند آپلود خطایی رخ دهد، اجرا می‌گردد. نحوه‌ی کدنویسی آن و بررسی خطاهای آن به شرح زیر است:
error: function(err, file) {
        switch(err) {
            case 'BrowserNotSupported':
                alert('مرورگر از این فناوری پشتیبانی نمی‌کند')
                break;
            case 'TooManyFiles':
                // قصد آپلود همزمان فایل‌های بیشتری از حد مجاز تعیین شده دارید
                break;
            case 'FileTooLarge':
                //حداقل حجم یکی از فایل‌ها از حجم مجاز تعیین شده بیشتر است
                //برای دسترسی به نام آن فایل از کد زیر استفاده کنید
              //file.name
                break;
            case 'FileTypeNotAllowed':
                // نوع حداقل یکی از فایل‌ها با نوع‌ها مشخص شده ما یکی نیست
                break;
            case 'FileExtensionNotAllowed':
                // پسوند حداقل یکی از فایل‌ها مورد تایید نیست
                break;
            default:
                break;
        }
    }
 allowedfiletypes   نوع فایل‌های مجاز را تعیین می‌کند:
allowedfiletypes: 
['image/jpeg','image/png','image/gif']
 allowedfileextensions   پسوند فایل هایی که برای آپلود مجاز هستند را معرفی می‌کند.
allowedfileextensions:
 ['.apk','.jar']
 maxfilesize   حداکثر حجم مجاز برای هر فایل که به مگابایت بیان می‌شود.
 docOver   این رویداد زمانی اجرا می‌شود که فایل‌های درگ شده شما وارد محیط یا پنجره مرورگر می‌شود.
 uploadStarted 
 این رویداد زمانی اجرا میگردد که فرایند آپلود هر فایل به طور جداگانه در حال آغاز شدن است:
متغیر i در کد زیر شامل اندیس فایلی است که آپلودش آغاز شده است و این اندیس از صفر آغاز می‌شود.
متغیر file دسترسی شما را به اطلاعات یک فایل باز میکند مانند نام فایل.
متغیر len تعداد فایل هایی را که کاربر در محل آپلود رها کرده است، باز میگرداند.
function(i, file, len){

    },
uploadFinished 
با اتمام آپلود هر فایل، این رویداد فراخوانی می‌گردد. دو پارامتر اول آن، همانند سابق هستند. پارامتر response خروجی json ایی را که در سمت سرور برگرداندیم، به ما باز می‌گرداند. پارامتر بعدی، زمانی را که برای آپلود طول کشیده است، بر می‌گرداند.
 function(i, file, response, time) {
    }
progressUpdated 
این رویداد برای نمایش پیشرفت یک آپلود مناسب است که آخرین پارامتر آن یک عدد صحیح از پیشرفت فایل را بر می‌گرداند.
function(i, file, progress) {
    },
globalProgressUpdated 
این رویداد میزان پیشرفت کلیه فایل‌ها را به درصد باز می‌گرداند:
function(progress) {
        $('#progress div')
.width(progress+"%"); }
speedUpdated 
سرعت آپلود هر فایل را با کیلوبیت بر ثانیه مشخص می‌کند.
function(i, file, speed) {
    }
rename
در صورتی که قصد تغییر نام فایل ارسالی را دارید می‌توانید از این رویداد استفاده کنید. پارامتر name، نام اصلی فایل را بر می‌گرداند که می‌توانید آن را دستکاری کنید و نام جدیدی را به عنوان خروجی برگردانید. نمونه کاربردی از این رویداد
 rename: function(name) {
    }

beforeEach 
این رویداد قبل از آپلود هر فایل آغاز می‌گردد و برگرداندن مقدار false در آن باعث جلوگیری و کنسل شدن آپلود آن فایل می‌گردد.
function(file) {
    }

beforeSend 
پارامترهای اولی تکراری هستند ولی آخرین پارامتر یک تابع done را می‌توان به آن پاس کرد که قبل از اجرای کل عملیات آپلود صدا زده می‌شود.
 function(file, i, done) {
    }
رویدادی به اسم queuefiles هم هست تعداد فایل‌هایی را که میتوانند به طور موازی و همزمان آپلود گردند، مشخص می‌کند. ولی دراین حالت maxfiles مورد استفاده قرار نمی‌گیرد. جهت بررسی یک مثال عملی و همچنین کدهای سمت سرور در PHP میتوانید از این آموزش استفاده کنید.
با تستی که به صورت لوکال رو آن انجام دادم به نظر نمی‌رسد برای فایل‌های با حجم متوسط به بالا مناسب باشد و برای فایل‌های با حجم کم مناسب می‌باشد. یک فایل 8 مگابایتی در حالت لوکال 9 ثانیه آپلود آن زمان برد و برای فایل‌های بزرگتر، فایرفاکس دیالوگ Stop Script را نشان داد.

PlUpload
این کتابخانه متن باز هم بسیار کارآمد و ساده و قابل انعطاف است و مثالهای آماده زیادی دارد. سایت سابسن هم در بخش آپلود زیرنویس‌ها از این کتابخانه استفاده می‌کند. از آنجا که آموزش این کتابخانه در سایت جاری آمده است از ذکر نکات بیشتر در مورد آن خودداری می‌نماییم.

Bootstrap FileStyle
اگر از قالب بوت استراپ استفاده می‌کنید و دوست دارید روی المان input file  قدیمی، ولی به شکلی مدرن کار کنید این کتابخانه هم فراموش نشود.

DropZoneJS
این کتابخانه به نسبت DropFile امکانات بیشتری را دارد و در سایت اختصاصی آن مثال‌ها و مستندات خوبی قرار گرفته است. در ساده‌ترین حالت آن ابتدا فایل کتابخانه  را صدا زده و سپس تگ فرم را به آن نسبت دهید:
<script src="https://rawgit.com/enyo/dropzone/master/dist/dropzone.js"></script>

<form action="/upload-target" class="dropzone"></form>
ولی اگر بخواهید آن را به سمت سرور ارسال کنید و  از آنجا آن را کنترل کنید، کد فرم را به شکل زیر تغییر دهید:
ابتدا بسته‌ی نیوگت آن را صدا بزنید:
Install-Package dropzone

با نصب این کتابخانه یک سری فایل CSS هم به سیستم اضافه می‌شود که می‌توانید برای استایل دهی هر چه بیشتر از آن بهره ببرید. کد فرم را به شکل زیر تغییر دهید:
    <form action="~/Home/SaveUploadedFile" method="post" enctype="multipart/form-data" class="dropzone" id="dropzoneForm" style="width: 50px; background: none; border: none;">
        <div class="fallback">
            <input name="file" type="file" multiple />
            <input type="submit" value="Upload" />
        </div>
    </form>
تگی که با کلاس fallback مزین شده است موقعی به کار می‌آید که مرورگر از این کتابخانه پشتیبانی نکرده و مجبور به نمایش یک آپلود معمولی می‌شویم.
با استفاده از کدنویسی هم می‌توان یک المان را به یک آپلودر تبدیل کرد:
var myDropzone = new Dropzone("div#myId", { url: "/file/post"});

//============ OR ====================
$("div#myId").dropzone({ url: "/file/post" });
همانطور که می‌بینید الزامی برای اینکه از یک تگ فرم استفاده کنید ندارد.
برای کانفیگ آپلودرهایی که از طریف المانهای Html ایجاد می‌شوند، می‌توان از کد زیر استفاده کرد و یک تنظیم عمومی برای تمامی آپلودرهای html آن صفحه ایجاد کرد.
Dropzone.options.myId= {
  paramName: "file", //نام پارامتری که فایل از طریق آن انتقال می‌بابد
  maxFilesize: 2, // MB
  accept: function(file, done) {
    if (file.name == "justinbieber.jpg") {
      done("Naha, you don't.");
    }
    else { done(); }
  }
};
تابع بالا یک آرگومان از نوع file را برگردانده و اگر این تابع، تابع done را با پارامتری رشته‌ای صدا بزند، عملیات آپلود آن فایل کنسل شده و پیام خطایی را نمایش می‌دهد و در صورتیکه بدون پارامتر صدا زده شود، عمل آپلود بدون مشکل انجام می‌شود.
ازآنجا که این کتابخانه از تنظیمات وسیعی استفاده می‌کند و از حوصله‌ی این مقاله خارج است، بهتر هست که صفحه‌ی مستندات آن را که کامل هم هست، مطالعه بفرمایید. از سری قابلیت‌هایی که پشتیبانی می‌کند: موارد پوشش داده شده در FileDrop، ساخت layout، ایجاد صف، متد حذف و اضافه و از این قبیل، ایجاد تصویر تمبر مانند و ...

یک نکته تکمیلی در مورد آپلود: در ASP.net به طور پیش فرض نهایت حجم فایل آپلودی 4 مگابایتی تعیین شده است که میتوانید آن را از طریق web.config تغییر دهید:
<configuration>
    <system.web>
        <httpRuntime maxRequestLength="1048576" />
    </system.web>
</configuration>
برای IIS 7 به بعد هم از تکه کد زیر استفاده کنید:
<system.webServer>
   <security>
      <requestFiltering>
         <requestLimits maxAllowedContentLength="1073741824" />
      </requestFiltering>
   </security>
 </system.webServer>
در هر دو کد بالا نهایت حجم بر روی یک گیگابایت تعیین شده است که maxRequestLength به صورت کیلوبایت و maxAllowContentLength به صورت بایت تعیین شده است. توصیه می‌شود هر دو شکل آن را وارد کنید. به خصوص که IIS Express از کد ابتدایی استفاده می‌کند و بخواهید نتیجه‌ی آن را در تست‌ها ببینید.

بازخوردهای پروژه‌ها
چند پیشنهاد
با تشکر از ایده و نرم افزار جالب شما، چند ایده به نظر بنده می‌تواند کمک کننده باشد:
1. دانلود خودکار یا غیر خودکار آخرین دیتابیس توسط برنامه
2. تبدیل لینک‌های داخلی از لینک به سایت به لینک در سطح داخلی برنامه
3. دانلود عکس‌ها و فایل‌های مرتبط جهت ایجاد نسخه 100% آفلاین
4. ایجاد امکان full screen برای html viewer برای خواندن ساده‌تر متون
نظرات مطالب
یافتن لیست اسمبلی‌های ارجاعی
خیلی ممنون آقای نصیری ... ولی یه قضیه برام حل نشد . شما گفتید که: "کلاینت‌ها هر کدام نسخه‌ی کامل و لوکال خودشون رو باید داشته باشند (از طریق check out مخزن کد این پروژه لوکال باید تشکیل شود نه کپی دستی). سپس مثل اینکه دارند لوکال کار می‌کنند (نه از روی شبکه در حالت مپ شده). "
چجوری باید بدون اینکه اونا سرور رو مپ کنند و یا اینکه فایل ها رو خودشون کپی کنند به سورس ها دسترسی داشته باشند ؟

من الان دارم Viusal SVN Server رو دانلود میکنم , اما قبل این هم از Ankh-SVN-2.0.6347 استفاده میکردم که کار هم باهاش بسیار آسان بود ... اگر لطفی بکنید و در مورد ساخت نسخه مخصوص کلاینت ها یه توضیح بدید ممنون میشم .
مطالب
سرنوشت Mono در هاله‌ای از ابهام

همانطور که مطلع هستید، شرکت Attachmate، شرکت ناول را مدتی قبل خرید. در این بین، شرکت Attachmate قصد دارد SUSE Linux را ادامه داده اما پروژه Mono را خاتمه دهد. متن زیر خلاصه‌ای از مصاحبه با Jeff Hawn، مدیر شرکت Attachmate است:
"واحد مرکزی پروژه SUSE به آلمان (هامبورگ) منتقل شده و تصمیمات اصلی مرتبط با مباحث توسعه لینوکس (که قبلا توسط تیم ناول صورت می‌گرفت)، توسط واحد هامبورگ انجام خواهد شد. به این ترتیب این واحد تصمیم گرفته است تا تعداد زیادی از کارکنان آمریکایی ناول را بازخرید کند (حدود 800 نفر، یا 50 درصد کارمندان آمریکایی پیشین ناول را)."

در این بین دقیقا مشخص نشده که تکلیف "Miguel de Icaza" - مدیر تیم Mono - چه شده است. حدس زده می‌شود که تیم سی نفره Mono هم جزو این 800 نفر کارمند آمریکایی بازخرید شده باشند (و آقای de Icaza هم تاکنون در بلاگ خود مطلبی را در این مورد منتشر نکرده و ترجیح داده است که سکوت کند).
در کل پایانی را برای پروژه‌های سورس باز نمی‌توان متصور شد؛ اما بدیهی است سرعت توسعه مداوم آن کاهش خواهد یافت.
جالب است بدانید Banshee که مدیاپلیری است مبتنی بر Mono ، به عنوان مدیاپلیر پیش فرض Ubuntu-11.04 مورد استفاده قرار گرفته است.


نظر یکی از خوانندگان مطلب ZDNet فوق هم در این مورد جالب بود:
مونو، توسعه تحت لینوکس را از درد به لذت تبدیل کرده است! سی پلاس پلاس زبان بزرگی است اما سرعت توسعه با مونو 20 برابر زمانی است که بخواهید با ++C کار کنید.

بازخوردهای دوره
بررسی مقدماتی مراحل کامپایل یک قطعه کد سی‌شارپ و آشنایی با OpCodes
یک نمونه از این پروژه‌ها، پروژه Code Refractor است. خلاصه کاری که انجام می‌دهد شامل مراحل زیر است:
- اسمبلی دات نتی را می‌خواند و bytecodes/operations آن‌را استخراج می‌کند.
- پس از آن، نتیجه را تبدیل به یک کد میانی خاص خودش می‌کند.
- این کد میانی خاص خودش را به ++C ترجمه می‌کند.
- نهایتا از یک کامپایلر ++C برای تولید فایل اجرایی نهایی استفاده خواهد کرد.
اطلاعات بیشتر