اشتراکها
گوگل چگونه کار میکند؟
مطالب
لینکهای هفته دوم دی
وبلاگها ، سایتها و مقالات ایرانی (داخل و خارج از ایران)
- شیوهنامه فارسیپسند گوگلخوان، نسخه ۰.۱.۱ (کار جالبی است. آشنایی با افزونه استایلیش)
ASP. Net
طراحی و توسعه وب
PHP
اسکیوال سرور
سی شارپ
SharePoint
عمومی دات نت
ویندوز
مسایل اجتماعی و انسانی برنامه نویسی
متفرقه
- آشنایی با لولههای یاهو و همچنین نمونهای دیگر
پیش نویس: این مقاله ترجمه شده فصل 6 کتاب Pro Asp.Net Core MVC2 میباشد.
کار با Visual Studio
در این مقاله، یکسری توضیحاتی در مورد ویژگیهای کلیدی ویژوال استودیو به برنامه نویسهای (توسعه دهندههای) پروژههای Asp.net Core MVC ارائه میدهیم.
ایجاد یک پروژه
در ابتدا یک پروژهی وب جدید Asp.net core را به نام Working و بر اساس قالب Empty ایجاد میکنیم. سپس در کلاس startup، قابلیت MVC را فعال میکنیم (کدهای این قسمت، در فصل 5 کامل شرح داده شدهاست)
namespace Working { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } //app.Run(async (context) => //{ // await context.Response.WriteAsync("Hello World!"); //}); } } }
ایجاد مدل:
یک پوشه جدید را به نام Models ایجاد میکنیم و بعد در این پوشه یک کلاس جدید را به نام Product ایجاد میکنیم و کدهای زیر را در کلاس ایجاد شده قرار میدهیم (این قسمت در فصل 5 نیز شرح داده شدهاست):
namespace Working.Models { public class Product { public string Name { get; set; } public decimal Price { get; set; } } }
namespace WorkingWithVisualStudio.Models { public class SimpleRepository { private static SimpleRepository sharedRepository = new SimpleRepository(); private Dictionary<string, Product> products = new Dictionary<string, Product>(); public static SimpleRepository SharedRepository => sharedRepository; public SimpleRepository() { var initialItems = new[] { new Product { Name = "Kayak", Price = 275M }, new Product { Name = "Lifejacket", Price = 48.95M }, new Product { Name = "Soccer ball", Price = 19.50M }, new Product { Name = "Corner flag", Price = 34.95M } }; foreach (var p in initialItems) { AddProduct(p); } } public IEnumerable<Product> Products => products.Values; public void AddProduct(Product p) => products.Add(p.Name, p); } }
نکته: من یک مشخصه (Property) استاتیک را به نام SharedRepository تعریف کردم که دسترسی به SimpleRepository را فراهم میکند و میتواند در طول برنامه از آن استفاده شود. این بهترین کار نیست، ولی میخواهم یک مشکل رایج را که در توسعه MVC روبرو میشوید، نشان دهم. من راه بهتری را برای کار با اجزای مشترک، در فصل 18 توضیح میدهم.
ایجاد Controller و View
در پوشه Controllers، یک فایل جدید را به نام HomeController.cs ایجاد میکنیم و کدهای زیر را در آن قرار میدهیم:
namespace WorkingWithVisualStudio.Controllers { public class HomeController : Controller { public IActionResult Index() => View(SimpleRepository.SharedRepository.Products); } }
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>>Working with Visual Studio</title> </head> <body> <table> <thead> <tr> <td>Name</td> <td>Price</td> </tr> </thead> <tbody> @foreach (var p in Model) {<tr> <td>@p.Name</td> <td>@p.Price</td> </tr>} </tbody> </table> </body> </html>
این View شامل یک جدول است که از حلقه foreach Razor، برای ایجاد ردیفهایی برای هر شیء مدل استفاده میکند. جایی که هر ردیف، حاوی سلولهایی برای خواص نام و قیمت است. اگر شما برنامه کاربردی را اجرا کنید، نتایج حاصل را در شکل خواهید دید:
دو نوع مختلف از بستههای نرم افزاری مورد نیاز برای Asp.Net Core MVC وجود دارند.
معرفی NuGet
ویژوال استودیو به همراه یک ابزار گرافیکی برای مدیریت بستههای NET. است که در یک پروژه گنجانده شدهاست. برای باز کردن این ابزار، گزینه Management NuGet Packages for Solution را از منوی Tools ➤ NuGet Package Manager انتخاب کنید. به این ترتیب ابزار NuGet باز میشود و لیستی از بستههایی که قبلا نصب شدهاند، نمایش داده میشود؛ همانطور که در شکل زیر نشان داده شدهاست:
برگهی Installed، خلاصهای از بستههایی را که قبلا در پروژه نصب شدهاند، نشان میدهد. از برگهی Browse، برای یافتن و نصب بستههای جدید میتوان استفاده کرد و برگهی Updates، فهرست package هایی را که نسخههای اخیر آنها منتشر شدهاند، نمایش میدهد.
معرفی بستهی MICROSOFT.ASPNETCORE.ALL
اگر شما از نسخههای قبلی Asp.Net Core استفاده کرده باشید، باید یک لیست طولانی از بستههای NuGet را به پروژه جدید خود اضافه نمایید. Asp.Net Core2 یک بستهی متفاوت را به نام Microsoft.AspNetCore.All معرفی میکند.
پکیچ Microsoft.AspNetCore.All یک meta-package است که شامل تمام بستههای Nuget مورد نیاز Asp.net Core و MVC Framework است. یعنی شما دیگر نیازی به نصب تک به تک این نوع بستهها ندارید و هنگامیکه برنامه خود را منتشر میکنید، هر بستهای از بستههای Meta-package که مورداستفاده قرار نمیگیرند، حذف خواهند شد. البته این بسته در نگارش 2.1، قسمت All آن به App تغییر نام یافتهاست.
معرفی بستههای Nuget و موقعیت ذخیره سازی آنها
ابزار NuGet لیست بستههای پروژه را در فایل projectname.csproj نگهداری میکند. در اینجا <projectname> با نام پروژه جایگزین میشود. برای مثال در پروژه فوق اطلاعات Nuget، در فایل WorkingWithVisualStudio.csproj ذخیره میشوند. ویژوال استودیو محتویات فایل csproj را در پنجرهی Solution Explorer نمایش نمیدهد. برای ویرایش این فایل، روی پروژه در پنجرهی Solution Explorer راست کلیک کنید و گزینهی Edit WorkWithVisualStudio.csproj را از منوی باز شده، انتخاب کنید. ویژوال استودیو فایل را برای ویرایش باز میکند. فایل csproj یک فایل XML است و شما در آن عنصری را مانند قطعه کد زیر در آن میبینید که Asp.net Core Meta package را به پروژه اضافه میکند:
<ItemGroup> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> </ItemGroup>
هنگامیکه از NuGet برای اضافه کردن یک بسته به پروژهی خود استفاده میکنید، به صورت خودکار به همراه هر بستهای که به آن وابستگی دارد، نصب میشود. شما میتوانید بستههای Nuget و وابستگیهای آنها را در SolutionExpolrer از طریق گزینهی Dependencies -> Nuget مشاهده کنید که هر یک از بستههای موجود در فایل csproj و وابستگیهای آنها را نشان میدهد. برای نمونه بسته Meta-Package ASP.Net Core دارای تعداد زیادی وابستگی است؛ برخی از آنها در شکل زیر دیده میشوند:
معرفی Bower
یک بسته Client-Side، شامل محتوایی است که به مشتری ارسال میشود؛ مانند فایلهای جاوا اسکریپت، Css Stylesheets و یا تصاویر. از Nuget برای مدیریت این نوع فایلها در پروژه نیز استفاده میشود. اما اکنون Asp.Net Core MVC پشتیبانی توکاری را از یک ابزار مدیریت بستههای سمت کاربر، به نام Bower نیز ارائه میدهد. Bower یک ابزار منبع باز ( Open Source ) است که در خارج از مایکروسافت و دنیای NET. توسعه داده شده و نگهداری میشود.
نکته: Bower به تازگی منسوخ شده اعلام گردیدهاست. ممکن است هشدارهایی را که ابزارهای جایگزین را پیشنهاد میکنند نیز مشاهده کنید. با این حال پشتیبانی از Bower با ویژوال استودیو یکپارچه شدهاست و در نگارش 2.1 ابزار مدیریت سمت کلاینت جدید دیگری را نیز بجای آن معرفی کردهاند.
معرفی لیست بستههای Bower
بستههای Bower از طریق فایل ویژهی bower.json مشخص میشوند. برای ایجاد این فایل در پنجره Solution Explorer روی پروژه WorkingWithVisualStudio راست کلیک کنید و Add -> New Item را از منوی باز شده انتخاب کنید. سپس قالب مورد نظر Bower Configuration File را از Asp.net Core -> Web -> General Category انتخاب نمائید؛ مانند تصویر زیر:
ویژوال استودیو نام bower.json را برای آن قرار میدهد. برروی ok کلیک میکنیم و یک فایل جدید، با محتویات پیشفرض زیر به پروژه اضافه میشود:
{ "name": "asp.net", "private": true, "dependencies": {} }
به علاوه برای فایل Bower.json، تصویر زیر بستههای Client Side وابسته به Bower را نشان میدهد. از این قسمت برای اضافه کردن وابستگیهای برنامه نیز استفاده میشود.
نکته: منبع بستههای Bower در لینک http://bower.io/search وجود دارد. شما میتوانید بستهها مورنظر را در اینجا جستجو و به پروژه اضافه کنید.
بعد از اینکه بستهها نصب شدند، محتویات فایل bower.json به صورت زیر میباشد:
{ "name": "asp.net", "private": true, "resolutions": { "jquery": "3.3.1" } }
در ادامه بسته Bootstrap CSS به پروژه اضافه شدهاست. زمانیکه شما فایل Bower.json را ویرایش میکنید، ویژوال استادیو لیستی از نام بستهها و نسخههای بستههای موجود را نمایش میدهد؛ مانند تصویر زیر:
در زمان نوشتن این مطلب، آخرین نسخهی پایدار بسته بوت استرپ، 3،3،7 است. البته اگر در دقت کنید، در اینجا سه گزینهی ارائه شدهی توسط ویژوال استودیو وجود دارند: 3.3.7 و 3.3.7^ و 3.3.7~. شماره نسخه میتواند در طیف وسیعی از روشهای مختلف در فایل bower.json مشخص شود. مفیدترین آنها در جدول زیر شرح داده شدهاند. استفاده از شماره نسخه صریح یک بسته، امنترین راه برای مشخص کردن یک بسته است. این تضمین میکند که شما همیشه با همان نسخه کار میکنید؛ مگر اینکه عمدا فایل bower.json را برای پاسخ گویی به درخواستهای دیگری به روز رسانی کنید:
فرمت | توضیحات |
3.3.7 | بیان شماره مستقیم بسته نصب شده و تطبیق دقیق آن با شمار نسخه ، e.g ، 3.3.7 |
* | با استفاده از یک ستاره به Bower اجازه نصب آخرین نسخه را میدهد |
3.3.7 =<3.3.7< | پیشوند یک شماره نسخه با < یا =< به Bower اجازه میدهد تا هر نسخه از بستهای که بزرگتر یا بزرگتر مساوی آن نسخهی معین است، نصب شود |
3.3.7 =>3.3.7> | پیشوند یک شماره نسخه با > یا => به Bower اجازه میدهد تا هر نسخه از بستهای را که کوچکتر یا کوچکتر و مساوی نسخهی معین است، نصب شود |
3.3.7~ | پیشوند یک شماره نسخه با یک tilde (با کاراکتر ~ ) به نسخههایی که دو شماره
اولیه آنها مشابه باشند، اجازه نصب میدهد؛ حتی اگر شماره آخر آن نسخه متفاوت
باشد. مانند نسخههای 3.3.9 و 3.3.8 و اجازه نصب نسخه 3.4.0 را نمیدهد؛ چون
شماره دوم آن متفاوت است. |
3.3.7^ | پیشوند یک شماره نسخه با یک قلم (کاراکتر ^) به نسخههایی که شماره اول آنها مشابه باشند، اجازه نصب میدهد؛ حتی اگر شماره دوم آنها متفاوت باشد. مانند نسخههای 3.3.1 و 3.4.1 و 3.5.1 اما نسخه 4.0.0 اجازه نصب ندارد |
نکته: برای مثال در این کتاب، من فایل bower.json را مستقیما ایجاد و ویرایش میکنم. ویرایش این فایل ساده است و به شما کمک میکند تا اطمینان حاصل کنید که نتایج مورد انتظار را در صورت پیگیری به همراه داشته باشد. همچنین ویژوال استودیو ابزار گرافیکی را نیز برای مدیریت بستههای bower فراهم میکند. شما میتوانید با کلیک راست بر روی فایل bower.json و انتخاب Manage Bower packages به منوی باز شده دسترسی داشته باشید. ویژوال استادیو فایلهای bower.json را برای تغییرات نظارت میکند و به صورت خودکار از ابزار Bower برای دانلود و نصب بستهها استفاده میکند. هنگامیکه شما تغییرات فایل را ذخیره میکنید، ویژوال استودیو بستهی BootStrap را دانلود میکند و در پوشهی wwwroot/lib ذخیره میکند.
مانند Nuget نیز Bower وابستگیهای مرتبط با بستههای اضافه شدهی به یک پروژه را مدیریت میکند. BootStrap برای دسترسی به برخی از ویژگیهای پیشرفته، به JQuery که یک کتابخانهی جاوا اسکریپتی است، تکیه میکند. به همین دلیل است که دو بسته را در شکل فوق نشان داده است. شما میتوانید لیست بستهها و وابستگیهای آنها را به صورت باز شده در بخش مورد نظر در Solution Explorer مشاهده کنید.
در ادامه کتاب، من از نسخه قبلی Bootstrap CSS framework استفاده میکنم. هنگامی که دارم این را مینویسم، تیم Bootstrap در حال توسعهی نسخهی 4 bootStrap است و چندین بار منتشر شدهاست. این نسخهها به عنوان "آلفا" برچسب گذاری شدهاند، اما کیفیت آنها بالا است و برای استفاده در نمونههای این کتاب به اندازه کافی پایدار است. با توجه به انتخاب نوشتن این کتاب با استفاده از Bootstrap 3 و نسخه پیش از نسخه بوت استرپ 4 و به زودی بایگانی شدن آن، تصمیم گرفتم از نسخه جدید استفاده کنم؛ حتی اگر برخی از نامهای کلاسها که برای شیوه نامههای عناصر HTML استفاده میشوند، احتمالا قبل از انتشار نهایی تغییر یابند. این مورد به این معنا است که شما باید همان نسخه از Bootstrap را که برای گرفتن نتایج موردنظر از خروجی نیاز دارید، استفاده کنید.
برای به روزرسانی بسته Bootstrap، شماره نسخه را در فایل bower.json تغییر دهید. مانند کد زیر:
{ "name": "asp.net", "private": true, "dependencies": { "bootstrap": "4.0.0-alpha.6" } }
زمانی که شما تغییرات فایل bower.json را ذخیره میکنید، ویژوال استودیو نسخه جدید BootStrap را دانلود میکند.
معرفی توسعه و کامپایل مداوم توسعه نرم افزار وب اغلب میتواند یک فرآیند تکراری باشد، جایی که تغییرات کوچکی را به ویووها یا کلاسها میدهید و برنامه را اجرا میکنید تا اثرات آن را آزمایش کنید. MVC و ویژوال استودیو همکاری میکنند تا از این رویکرد مداوم استفاده کنند تا تغییرات را سریعتر و آسانتر ببینید.
اعمال تغییرات در Razor Views
در زمان توسعه، تغییراتی که به Razor View اعمال میشوند، به محض رسیدن درخواستهای HTTP، از مرورگر دریافت میشوند. برای اینکه ببینید چطور کار میکند، برنامه را با انتخاب گزینه Start Debugging از منوی Debug اجرا کنید و هنگامیکه یک برگهی مرورگر باز شد و اطلاعات نمایش داده شد، تغییراتی را که در زیر نمایش میدهم در فایل Index.cshtml اعمال کنید.
@model IEnumerable<WorkingWithVisualStudio.Models.Product> @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>>Working with Visual Studio</title> </head> <body> <h3>Products</h3> <table> <thead> <tr> <td>Name</td> <td>Price</td> </tr> </thead> <tbody> @foreach (var p in Model) { <tr> <td>@p.Name</td> <td>@($"{p.Price:C2}")</td> </tr>} </tbody> </table> </body> </html>
اعمال تغییرات در کلاسهای #C
برای کلاسهای #C، از جمله کنترلرها و مدلها، دو رویکرد موجود را که از طریق آیتمهای مختلف در منوی Debug انتخاب میشوند، شرح میدهم:
Start Without Debugging
تغییرات در کلاسها در پروژه به صورت خودکار زمانیکه یک درخواست HTTP دریافت میشود، برای مشاهدهی یک تجربهی توسعهی پویا، کامپایل میشوند. در این حالت برنامه بدون امکانات دیباگ و اشکالزادیی اجرا میشود.
Start Debugging
به شما اجزا میدهد صریح تغییرات را کامپایل کنید و برنامه را اجرا کنید ، بررسی مشکلات هم در زمان اجرا پروژه انجام میگیرد.به شما اجرا بررسی و تجزیه و تحلیل هر گونه مشکل در کد را میدهد.
کامپایل خودکار کلاس ها
در طول توسعه عادی، این چرخه کامپایل سریع به شما اجازه میدهد تا فورا تاثیر تغییرات خود را ببینید؛ حالا میتواند این تغییر اضافه نمودن یک اکشن جدید و یا ویرایش نمایش اطلاعات یک Model باشد. برای ارائهی این نوع از توسعه، ویژوال استودیو به محض رسیدن درخواست HTTP از مرورگر، تغییرات را دریافت و کلاسها را به صورت خودکار کامپایل میکند. برای دیدن اینکه چگونه کار میکند، گزینه Start Without Debugging را از منوی Debug در ویژوال استودیو انتخاب کنید. هنگامیکه مرورگر دادههای برنامه را نمایش میدهد، تغییرات زیر را در فایل Home controller ایجاد کنید:
namespace WorkingWithVisualStudio.Controllers { public class HomeController : Controller { public IActionResult Index() => View(SimpleRepository.SharedRepository.Products .Where(p => p.Price < 50)); } }
namespace WorkingWithVisualStudio.Models { public class SimpleRepository { private static SimpleRepository sharedRepository = new SimpleRepository(); private Dictionary<string, Product> products = new Dictionary<string, Product>(); public static SimpleRepository SharedRepository => sharedRepository; public SimpleRepository() { var initialItems = new[] { new Product { Name = "Kayak", Price = 275M }, new Product { Name = "Lifejacket", Price = 48.95M }, new Product { Name = "Soccer ball", Price = 19.50M }, new Product { Name = "Corner flag", Price = 34.95M } }; foreach (var p in initialItems) { AddProduct(p); } products.Add("Error", null); } public IEnumerable<Product> Products => products.Values; public void AddProduct(Product p) => products.Add(p.Name, p); } }
مشکلی مانند ورودی Null تا زمانیکه برنامه اجرا نشود، نمایش داده نمیشود. بارگذاری صفحه مرورگر باعث میشود کلاس SimpleRepository به صورت خودکار کامپایل شود و برنامه دوباره راه اندازی خواهد شد. هنگامیکه MVC نمونهای از کلاس Controller را برای پردازش درخواست HTTP از مرورگر ایجاد میکند، سازنده HomeController کلاس SimpleRepository را ایجاد خواهد کرد که به نوبه خود سعی میکند مقدار Null اضافه شده در لیست را پردازش کند. مقدار Null باعث بروز یک مشکل میشود، اما مشخص نیست مشکل چیست. مرورگر یک پیام مفید را نمایش نمیدهد.
توانایی نمایش صفحات خطاها
زمانیکه مشکلی در پنجرهی مرورگر ایجاد شد، میتوان یک راهنمای با اطلاعات مفید را نمایش داد. این قابلیت را میتوانید با فعال کردن نمایش صفحات انجام داد که باید در تنظیمات کلاس Startup تغییرات زیر را اعمال کنید.namespace WorkingWithVisualStudio { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseDeveloperExceptionPage(); } } } }
استفاده از Debugger
ویژوال استادیو از اجرای یک برنامه MVC با استفاده از Debugger نیز پشتیبانی میکند که اجازه میدهد برنامه برای بررسی وضعیت نرم افزار و دنبال کردن درخواستی که به برنامه ارسال میشود، متوقف و از این طریق، پیگیری شود. این مورد نیاز به یک سبک متفاوت از توسعه را دارد. زیرا تغییراتی را در کلاسهای #C میدهیم، تا زمانیکه برنامه مجددا راه اندازی نشود، اعمال نمیشوند ( هرچند تغییرات Razor View هنوز هم به صورت خودکار اعمال میشوند). این سبک توسعه به همراه استفادهی از ویژگی کامپایل خودکار نیست؛ اما Debugger ویژوال استودیو عالی است و میتواند بینش عمیقتری را در مورد نحوهی کارکرد برنامه داشته باشد. برای اجرای برنامه با استفاده Debugger، در ویژوال استودیو از منوی Debug گزینهی Start Debugging را انتخاب کنید. ویژوال استودیو کلاسهای #C در پروژه را قبل از اجرای برنامه کامپایل میکند. اما شما همچنان میتوانید با استفاده از موارد موجود در منوی Build، کد خود را به صورت دستی نیز کامپایل کنید.
مثال فوق حاوی مقدار NULL است که سبب میشود یک NullReferenceException توسط کلاس SimpleRepository پرتاب شود. این حالت برنامه را قطع و کنترل اجرا را به توسعه دهنده منتقل میکند؛ همانطور که در شکل زیر نشان داده شده است
نکته: اگر Debugger خطا را نفهمد، گزینهی Windows ➤ exception settings را از منوی Debugger ویژوال استودیو انتخاب کنید و اطمینان حاصل کنید که تمام انواع خطاهای در لیست خطاهای زمان اجرای زبان مشترک، تایید شدهاست.
تنظیم یک Break-point Debugger عامل اصلی خطا را نمایش نمیدهد؛ تنها مکان آنرا آشکار میکند. عبارتیکه ویژوال استودیو برجسته میکند نشان میدهد که این مشکل زمانی رخ میدهد که فیلتر کردن اشیاء با استفاده از LINQ انجام شود، اما یک کار کوچک لازم است تا از جزئیات کاسته شود و به علت اصلی برسد.
Breakpoint عبارتی است که به Debugger میگوید تا برنامه را متوقف کند و کنترل دستی برنامه را به برنامه نویس میدهد. شما میتوانید وضعیت برنامه را بازبینی کنید و ببینید چه اتفاقی میافتد و به صورت اختیاری روند کاری را دوباره ادامه دهید.
برای ایجاد Breakpoint، روی عبارت راست کلیک کنید و در منوی باز شده، گزینه Breakpoint -> Insert Breakpoint را انتخاب کنید.
به عنوان مثال: یک Breakpoint به خط کد AddProduct در کلاس SimpleRepository اعمال کنید. همانطور که در شکل زیر نمایش داده میشود:
برنامه را اجرا کنید؛ با استفاده از Debug -> Start Debugging و یا با استفاده از Debug -> Restart برنامه را Restart میکنیم. در طی درخواست اولیه HTTP، برنامه اجرا میشود تا به نقطهای که Break Point دارد برسد و در آنجا برنامه متوقف میشود. در این نقطه، شما میتوانید از آیتمهای منوی Debug ویژوال استودیو یا کنترلها در بالای پنجره، برای کنترل اجرای برنامه استفاده کنید؛ یا از نمایشهای مختلف Debugger موجود از طریق Debug -> Windows برای بررسی وضعیت برنامه استفاده میکنیم.
مشاهده مقادیر داده در ویرایشگر کد
رایجترین استفاده Break Point، ردیابی مشکلات در کد شماست. قبل از اینکه بتوانید یک مشکل را رفع کنید، باید بدانید چه اتفاقی در حال رخ دادن است و یکی از ویژگیهای مفید ویژوال استودیو این است که توانایی مشاهده و کنترل ارزش متغیرها را درست در ویرایشگر کد، میدهد.اگر اشارهگر ماوس را بر روی پارامتر p به متد AddProduct که توسط Debugger برجسته شدهاست، حرکت دهید، یک فرم ظاهر خواهد شد که ارزش فعلی p را نشان میدهد؛ همانطور که در شکل زیر نشان داده شدهاست. من یک نمونه بزرگ شده از محتویات فرم ظاهر شده را نمایش میدهم تا به راحتی بتوانید متن در آن را بخوانید.
این مورد ممکن است مؤثر به نظر نرسد، چون شیء داده در یک سازنده همانند BreakPoint تعریف شدهاست. اما این ویژگیها برای هر متغیری کار میکند. شما میتوانید مقادیر را مشاهده کنید تا مقادیر خود و فیلد آنها را ببینید. هر مقدار دارای یک دکمه پین کوچک به سمت راست است. برای زمانیکه کد در حال اجراست، برای نظارت بر مقدار، از آن استفاده کنید.
اشارهگر ماوس را بر روی متغیر P قرار دهید و مرجع محصول را پین کنید. مرجع پیوست شده را باز کنید تا بتوانید نام و قیمت را نیز ببینید؛ مانند شکل زیر:
گزینه Continue را از منوی Debug در ویژوال استادیو انتخاب کنید تا برنامه ادامه پیدا کند. از آنجا که در برنامه حلقه Foreach وجود دارد، برنامه که دوباره اجرا میشود، وقتی مجددا به BreakPoint رسید، برنامه متوقف میشود. مقادیر پین شده در شکل زیر نشان میدهند که چگونه متغیر P و خواص آن تغییر میکنند.
استفاده از پنجره متغیرهای محلی ( Local Windows )
یکی از ویژگیهای مرتبط، پنجره Locals است که با انتخاب گزینهی منوی Debug ➤ Windows ➤ Locals باز میشود. پنجرهی Locals، مقدار متغیرها را به شکلی مشابه پنل پین شده نمایش میدهد، اما در اینجا تمام اشیاء محلی را نسبت به Break Point نمایش میدهد؛ همانطور که در شکل زیر نشان داده شدهاست:
هربار که Continue را انتخاب میکنید، اجرای برنامه ادامه یافته و یک شیء دیگر توسط حلقه foreach پردازش میشود.
اگر ادامه دهید، در زمان ویرایش کد، در هر دو پنجره Locals و در مقادیر پنل پین شده، شما مرجع Null را میبینید. برای کنترل اجرای برنامه، میتوانید جریان را از طریق کد خود در دیباگر دنبال کنید و احساس کنید که چه اتفاقی میافتد.
برای غیرفعال کردن BreakPoint، روی عبارت راست کلیک کنید و از منوی باز شده گزینه Delete BreakPoint را انتخاب کنید. برنامه را دوباره راه اندازی کنید و جدول داده سادهای را که در شکل نشان داده شده، مشاهده خواهید کرد.
استفاده از Browser Link
ویژگی Browser Link میتواند روند توسعه را با قرار دادن یک یا چند مرورگر تحت کنترل ویژوال استودیو، ساده سازی کند. این ویژگی مخصوصا مفید است اگر شما نیاز به دیدن اثر تغییرات را در طیف وسیعی از مرورگرها دارید. قابلیت Browser Link با و یا بدون Debugger کار میکند و به این معنا است که میتوانیم هر فایلی را در پروژه تغییر دهیم و تاثیر تغییر را بدون نیاز به تغییری در مرورگر مشاهده کنیم.
راه اندازی BrowserLink
برای فعال کردن Browser Link باید در کلاس Startup، تنظیمات را تغییر دهید. مانند کد زیر:
namespace WorkingWithVisualStudio { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); } } }
استفاده از Browser Link
برای درک اینکه Browser Link چگونه کار میکند، در ویژوال استودیو گزینه Start Without Debugging را از منوی Debug انتخاب میکنیم. ویژوال استودیو برنامه را اجرا میکند و یک برگه جدید مرورگر را برای نمایش نتیجه باز میکند. با بازبینی HTML ارسال شده به مرورگر، شما خواهید دید که حاوی بخش دیگری مانند این است:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>>Working with Visual Studio</title> </head> <body> <h3>Products</h3> <table> <thead> <tr><td>Name</td><td>Price</td></tr> </thead> <tbody> <tr><td>Lifejacket</td><td>£48.95</td></tr> <tr><td>Soccer ball</td><td>£19.50</td></tr> <tr><td>Corner flag</td><td>£34.95</td></tr> </tbody> </table> <!-- Visual Studio Browser Link --> <script type="application/json" id="__browserLink_initializationData"> {"requestId":"968949d8affc47c4a9c6326de21dfa03","requestMappingFromServer":false} </script> <script type="text/javascript" src="http://localhost:55356/d1a038413c804e178ef009a3be07b262/browserLink" async="async"></script> <!-- End Browser Link --> </body> </html>
ویژوال استادیو یک جفت عناصر اسکریپت را به HTML فرستاده شدهی به مرورگر اضافه میکند که برای بازکردن یک اتصال طولانی مدت HTTP با سرور برنامه کاربردی است؛ تا زمانیکه ویژوال استودیو مجددا برنامه را ریاستارت کند. کد زیر تغییر در فایل Index و تاثیر استفاده از Browser Link را نشان میدهد.
@model IEnumerable<WorkingWithVisualStudio.Models.Product> @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>>Working with Visual Studio</title> </head> <body> <h3>Products</h3> <p>Request Time: @DateTime.Now.ToString("HH:mm:ss")</p> <table> <thead> <tr> <td>Name</td> <td>Price</td> </tr> </thead> <tbody> @foreach (var p in Model) { <tr> <td>@p.Name</td> <td>@($"{p.Price:C2}")</td> </tr>} </tbody> </table> </body> </html>
کد جاوا اسکریپتی که در HTML ارسال شده به مرورگر جاسازی شده، صحفه را دوباره بارگذاری میکند؛ برای دیدن تاثیرات کد اضافه شده که اضافه کردن یک timestamp ساده است.
نکته: عناصر اسکریپت Browser Link فقط در پاسخهای موفق جاسازی شده است. به این معنا که اگر یک خطا هنگام کامپایل در هنگام اجرا کردن یک Razor View یا مدیریت یک درخواست ایجاد شود، اتصال بین مرورگر و ویژوال استودیو از بین میرود و شما بعد از حل مشکل باید صفحه را مجدد بارگذاری کنید.
استفاده از مرورگرهای متعدد
Browser Link میتواند برای نمایش یک برنامه در مرورگرهای متعددی به طور همزمان استفاده شود و میتواند زمانی مفید باشد که شما میخواهید تفاوتهای پیاده سازی را بین مرورگرهای مختلف کنترل کنید و یا ببینید که چگونه یک برنامه بر روی ترکیبی از مرورگرهای دسکتاپ و تلفن همراه ارائه میشود.
برای انتخاب مرورگرهایی که استفاده میشوند، مرورگر را با استفاده از دکمه IIS Express در نوار ابزار ویژوال استودیو، انتخاب کنید؛ همانطور که در شکل زیر نشان داده شده است.
ویژوال استودیو لیستی از مرورگرهایی را که در مورد آنها اطلاعاتی دارد، نمایش میدهد. در عکس زیر مرورگرهایی را که من در سیستم خود نصب کردهام، نشان میدهد. برخی از آنها با ویندوز مانند Internet Explorer و Edge نصب میشوند.
ویژوال استادیو معمولا مرورگرهای رایجی را که نصب میشوند، نمایش میدهد. اما شما میتوانید با استفاده از دکمهی Add، برای اضافه کردن مرورگری که به صورت خودکار لیست نشده نیز استفاده کنید. همچنین میتوانید ابزار تست شخص ثالث مانند Browser Stack را نیز راه اندازی کنید که مرورگرها را بر روی سرویسهای ابری میزبان ( cloud-hosted ) و ماشینهای مجازی اجرا میکند.
من سه مرورگر را در شکل انتخاب کردم: Chrome ، Internet Explorer و Edge. با کلیک بر روی دکمه Browse، فعالیت هر سه مرورگر شروع میشود و باعث میشود URL مثال برنامه را بارگذاری کند؛ همانطور که در شکل نشان داده شده است.
با استفاده از منوی Browser Link Dashboard، شما میتوانید ببینید که چه مرورگرهایی در Browser Link انتخاب شدهاند. داشبورد آن نشانی اینترنتی نمایش داده شده توسط هر مرورگر را نشان میدهد و در اینجا هر مرورگر را میتوان به صورت جداگانه رفرش کرد.
آماده سازی جاوا اسکریپت و CSS برای استقرار
هنگامی که Client-Side بخشی از یک برنامه وب را ایجاد میکنید، معمولا تعدادی از فایلهای جاوا اسکریپت و CSS سفارشی را تهیه میکنید که برای تکمیل آنها، از بستههای نصب شدهی توسط Bower استفاده میشود. این فایلها نیاز به پردازش دارند تا آنها را برای تحویل در یک محیط تولید، بهینه سازی کنند تا تعداد درخواستهای HTTP و میزان پهنای باند شبکه مورد نیاز برای ارسال آنها به مشتری، به حداقل برسد. این فرآیند به عنوان بسته بندی شناخته میشود.
فعال کردن تحویل محتوای استاتیک
ASP.Net Core شامل پشتیبانی از ارائه فایلهای استاتیک از پوشه wwwroot به مشتریان است. اما این امکان به صورت پیشفرض در زمان ایجاد یک پروژهی خالی جدید فعال نیست و شما باید با قرار دادن عبارتی در فایل StartUp آن را فعال کنید؛ مانند کد زیر:
namespace WorkingWithVisualStudio { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); app.UseStaticFiles(); app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); } } }
اضافه کردن محتوای استاتیک به پروژه
برای نشان دادن فرآیند بسته بندی، من نیاز به اضافه کردن تعدادی محتوای استاتیک به پروژه و یکی کردن آنها با برنامهی نمونه را دارم. برای این منظور ابتدا یک پوشهی جدید را به نام wwwroot/css ایجاد کنید که محل متداولی برای فایلهای سفارشی CSS است. من فایلی را به نام First.css با استفاده از قالب آیتم Style Sheet اضافه کردم؛ همانطور که در شکل زیر نشان داده شده است. قالب Style Sheet در مسیر Asp.Net Core -> Web -> Content Section وجود دارد.
فایل First.Css را ویرایش کنید و محتوای زیر را در آن قرار دهید.
h3 { } table, td { border: 2px solid black; border-collapse: collapse; padding: 5px; }
فایلهای جاوا اسکریپت معمولا در پوشه wwwroot/js قرار میگیرند. من این پوشه را ایجاد کردم. فایلهای جاوا اسکریپت را میتوانید در مسیر Asp.Net Core -> Web -> Script انتخاب کنید. همانطور که در شکل زیر نشان داده شده است.
من کد جاوا اسکریپتی ساده زیر را به این فایل جدید اضافه کردم؛ همانطور که در لیست نشان داده شده است.
document.addEventListener("DOMContentLoaded", function () { var element = document.createElement("p"); element.textContent = "This is the element from the third.js file"; document.querySelector("body").appendChild(element); });
من به بیش از یک فایل جاوا اسکریپت نیاز دارم. بنابراین فایل دیگری را به نام fourth.js نیز در پوشه wwwroot ایجاد میکنم و محتوای زیر را در آن قرار میدهم.
document.addEventListener("DOMContentLoaded", function () { var element = document.createElement("p"); element.textContent = "This is the element from the fourth.js file"; document.querySelector("body").appendChild(element); });
به روز رسانی View
گام نهایی، به روز رسانی فایل Index.cshtml برای استفاده از Css و فایل جاوا اسکریپت است. کدهای آن در زیر نشان داده شده است:
@model IEnumerable<WorkingWithVisualStudio.Models.Product> @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>>Working with Visual Studio</title> <link rel="stylesheet" href="css/first.css" /> <link rel="stylesheet" href="css/second.css" /> <script src="js/third.js"></script> <script src="js/fourth.js"></script> </head> <body> <h3>Products</h3> <p>Request Time: @DateTime.Now.ToString("HH:mm:ss")</p> <table> <thead> <tr> <td>Name</td> <td>Price</td> </tr> </thead> <tbody> @foreach (var p in Model) { <tr> <td>@p.Name</td> <td>@($"{p.Price:C2}")</td> </tr>} </tbody> </table> </body> </html>
اگر برنامه کاربردی را اجرا کنید، محتویات نشان داده شدهی در شکل زیر را مشاهده خواهید کرد. محتوای موجود توسط شیوه نامههای CSS شبیه سازی شده است و کد جاوا اسکریپتی جدیدی را اضافه کرده است.
یکی کردن فایلهای سمت کلاینت در برنامههای MVC
در حال حاضر چهار فایل استاتیک وجود دارند و مرورگر باید چهار درخواست را برای دریافت فایلهای استاتیک ایجاد کند و هر یک از این فایلها نیازمند پهنای باند بیشتری است که باید به مشتری تحویل داده شود؛ زیرا آنها حاوی فضای سفید و نام متغیرها هستند که برای توسعه دهندهها معنا دار هستند؛ اما برای مرورگرها اهمیتی ندارند.
ترکیب فایلهایی هم نوع، تلفیق نامیده میشود و در آن کار ساختن فایلها به صورتی کوچکتر انجام میشود. هر دوی این کارها در برنامه Asp.Net Core MVC توسط Bundler & Minifier مخصوص ویژوال استودیو انجام میشود.
نصب افزونههای ویژوال استودیو
اولین قدم برای نصب افزونه، انتخاب از منوی Tools -> Extensions and Update و کلیک بر روی مجموعه Online است تا افزونههای ویژوال استودیو را در مجموعه نمایش بدهد. نام افزونه را در جعبه جستجوی در گوشهی سمت راست بالای پنجره وارد کنید؛ همانطور که در شکل زیر نشان داده شده است. محل نصب افزونه را مشخص میکنیم و بر روی دانلود کلیک میکنیم تا آن را به ویژوال استودیو اضافه کند. ویژوال استودیو را مجدد راه اندازی کنید تا فرآیند نصب تکمیل شود.
دسته بندی و یکی کردن فایلها
پس از نصب افزونه، ویژوال استودیو را مجددا راه اندازی کنید و پروژه نمونه را باز کنید. با افزودن افزونه، میتوانید چندین فایل هم نوع را در Solution Explorer انتخاب کنید. آنها را با یکدیگر ترکیب کرده و محتویات آنها را کوچکتر کنید. به عنوان مثال فایلهای First.css و Second.css را در Solution Explorer را انتخاب و کلیک راست کرده و سپس Bundler & Minifier -> Bundle and Minify Files را از منوی باز شده انتخاب کنید . همانطور که در شکل زیر نشان داده شده است.
فایل خروجی را با عنوان bundle.css ذخیره کنید. در Solution Explorer یک بسته جدید ایجاد میشود. اگر شما این فایل را باز کنید، خواهید دید که محتویات هر دو فایل CSS جداگانه ترکیب شدهاند و تمام فضای سفید آنها حذف شدهاست. البته شما نمیخواهید به طور مستقیم با این فایل کار کنید؛ اما این فایل کوچکتر است و فقط یک اتصال HTTP را برای ارائه CSS styles به مشتری نیاز دارد.
مراحل قبل را برای فایلهای third.js و fourth.js تکرار کنید تا فایلهای جدید bundle.js و bundle.min.js در پوشه wwwroot ایجاد شوند.
احتیاط: اطمینان حاصل کنید که فایلها را به ترتیبی که توسط مرورگر بارگیری میشوند، انتخاب کنید تا ترتیب دستورات Styleها یا دستورات کد را در فایلهای خروجی حفظ کنید. به عنوان مثال دقت کنید که فایل third.js قبل از فایل fourth.js انتخاب شده باشد تا مطمئن باشید دستورات به ترتیب و به درستی اجرا میشوند.
کد زیر، عناصر پیوند فایلهای جداگانهای را که باید در فایل Index.cshtml قرار گیرند، نمایش میدهد:
@model IEnumerable<WorkingWithVisualStudio.Models.Product> @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>>Working with Visual Studio</title> <link rel="stylesheet" href="css/bundle.min.css" /> <script src="js/bundle.min.js"></script> </head> <body> <h3>Products</h3> <p>Request Time: @DateTime.Now.ToString("HH:mm:ss")</p> <table> <thead> <tr> <td>Name</td> <td>Price</td> </tr> </thead> <tbody> @foreach (var p in Model) { <tr> <td>@p.Name</td> <td>@($"{p.Price:C2}")</td> </tr>} </tbody> </table> </body> </html>
همان زمان که عملیات جمع آوری و یکی کردن را انجام میدهید، رکورد عملیات انجام شده را در فایلی به نام bundleconfig.json در پوشهی wwwroot پروژه نگهداری میکند. در اینجا یک نمونه از فایل تولیدی را مشاهده میکنید:
[ { "outputFileName": "Views/wwwroot/css/bundle.css", "inputFiles": [ "Views/wwwroot/css/First.css", "Views/wwwroot/css/second.css" ] }, { "outputFileName": "Views/wwwroot/js/bundle.js", "inputFiles": [ "Views/wwwroot/js/fourth.js", "Views/wwwroot/js/third.js" ] } ]
خلاصه
در این بخش من توضیحاتی را در مورد ویژگیهایی که ویژوال استودیو برای طراحی برنامههای وب به توسعه دهندهها ارائه میدهد، شرح دادم که شامل کامپایل خودکار کلاسها، Browser Link و یکی کردن فایلهای سمت کلاینت ( bundling and minification ) بود.
مطالب
لینکهای هفته اول دی
وبلاگها و سایتهای ایرانی
امنیت
ASP. Net
طراحی وب
PHP
- خبرهایی در مورد مایکروسافت و PHP
اسکیوال سرور
سی شارپ
عمومی دات نت
مسایل اجتماعی و انسانی برنامه نویسی
کتابهای رایگان جدید
متفرقه
- آهن بجای کروم! (یک برنامه نویس آلمانی قسمتهایی از مرورگر کروم را که در جهت جمع آوری اطلاعات برای گوگل بکار میرفته، حذف کرده و مرورگر دیگری به نام آهن را ارائه داده است!)
هدف از این مبحث، آشنایی با مفاهیم پایهای اغلب بانکهای اطلاعاتی NoSQL است که به صورت مشترکی در تمام آنها بکار رفته است. برای مثال بانکهای اطلاعاتی NoSQL چگونه مباحث یکپارچگی اطلاعات را مدیریت میکنند؟ نحوه ایندکس نمودن اطلاعات در آنها چگونه است؟ چگونه از اطلاعات کوئری میگیرند؟ الگوریتمهای محاسباتی مانند MapReduce چیستند و چگونه در اینگونه بانکهای اطلاعاتی بکار رفتهاند؟ همچنین الگوهای Sharding و Partitioning که در اغلب بانکهای اطلاعاتی NoSQL مشترکند، به چه نحوی پیاده سازی شدهاند.
لیست مشترکات بانکهای اطلاعاتی NoSQL
قبل از اینکه بخواهیم وارد ریز جزئیات بانکهای اطلاعاتی NoSQL شویم، نیاز است لیست و سرفصلی از مفاهیم اصلی و مشترک بین اینگونه بانکهای اطلاعاتی را تدارک ببینیم که شامل موارد ذیل میشود:
الف) Non-Relational یا غیر رابطهای
از کلمه NoSQL عموما اینطور برداشت میشود که در اینجا دیگر خبری از SQL نویسی نیست که در عمل برداشت نادرستی است. شاید جالب باشد که بدانید، تعدادی از بانکهای اطلاعاتی NoSQL از زبان SQL نیز به عنوان اینترفیسی برای نوشتن کوئریهای مرتبط، پشتیبانی میکنند.
کلمه NoSQL بیشتر به Non-Relational یا غیر رابطهای بودن اینگونه بانکهای اطلاعاتی بر میگردد. مباحثی مانند مدلهای دادهای نرمال شده، اتصالات و Join جداول، در دنیای NoSQL وجود خارجی ندارند.
ب) Non-schematized/schema free یا بدون اسکیما
مفهوم مهم و مشترک دیگری که در بین بانکهای اطلاعاتی NoSQL وجود دارد، بدون اسکیما بودن اطلاعات آنها است. به این معنا که با حرکت از رکورد یک به رکورد دو، ممکن است با دو ساختار دادهای متفاوت مواجه شوید.
ج) Eventual consistency یا عاقبت یک دست شدن
عاقبت یک دست شدن، به معنای دریافت دستوری از شما و نحوه پاسخ دادن به آن (یا حتی پاسخ ندادن به آن) از طرف بانک اطلاعاتی NoSQL است. برای مثال، زمانیکه یک رکورد جدید را اضافه میکنید، یا اطلاعات موجودی را به روز رسانی خواهید کرد، اغلب بانکهای اطلاعاتی NoSQL این دستور را بسیار سریع دریافت و پردازش خواهند کرد. اما تفاوت است بین دریافت پیام و پردازش واقعی آن در اینجا.
اکثر بانکهای اطلاعاتی NoSQL، پردازش و اعمال واقعی دستورات دریافتی را با یک تاخیر انجام میدهند. به این ترتیب میتوان خیلی سریع به بانک اطلاعاتی اعلام کرد که چه میخواهیم و بانک اطلاعاتی بلافاصله مجددا کنترل را به شما بازخواهد گرداند. اما اعمال و انتشار واقعی این دستور، مدتی زمان خواهد برد.
د) Open source یا منبع باز بودن
اغلب بانکهای اطلاعاتی NoSQL موجود، منبع باز هستند که علاوه بر بهره بردن از مزایای اینگونه پروژهها، استفاده کنندگان سورس باز دیگری را نیز ترغیب به استفاده از آنها کردهاند.
ه) Distributed یا توزیع شده
هرچند امکان پیاده سازی توزیع شده بانکهای اطلاعاتی رابطهای نیز وجود دارد، اما نیاز به تنظیمات قابل توجهی برای حصول این امر میباشد. در دنیای NoSQL، توزیع شده بودن جزئی از استاندارد تهیه اینگونه بانکهای اطلاعاتی است و بر اساس این مدل ذهنی شکل گرفتهاند. به این معنا که اطلاعات را میتوان بین چندین سیستم تقسیم کرد، که حتی این سیستمها ممکن است فواصل جغرافیایی قابل توجهی نیز با یکدیگر داشته باشند.
و) Web scale یا مناسب برای برنامههای تحت وب پر کاربر
امروزه بسیاری از کمپانیهای بزرگ اینترنتی، برای مدیریت تعداد بالایی از کاربران همزمان خود، مانند فیسبوک، یاهو، گوگل، Linkedin، مایکروسافت و غیره، نیاز به بانکهای اطلاعاتی پیدا کردهاند که باید در مقابل این حجم عظیم درخواستها و همچنین اطلاعاتی که دارند، بسیار بسیار سریع پاسخ دهند. به همین جهت بانکهای اطلاعاتی NoSQL ابداع شدهاند تا بتوان برای این نوع سناریوها پاسخی را ارائه داد.
و نکته مهم دیگر اینجا است که خود این کمپانیهای بزرگ اینترنتی، بزرگترین توسعه دهندههای بانکهای اطلاعاتی NoSQL نیز هستند.
نحوه مدیریت یکپارچگی اطلاعات در بانکهای اطلاعاتی NoSQL
مدیریت یکپارچگی اطلاعات بانکهای اطلاعاتی NoSQL به علت ذات و طراحی توزیع شده آنها، با نحوه مدیریت یکپارچگی اطلاعات بانکهای اطلاعاتی رابطهای متفاوت است. اینجا است که تئوری خاصی به نام CAP مطرح میشود که شامل یکپارچگی یا Consistency به همراه Availability یا دسترسی پذیری (همیشه برقرار بودن) و partition tolerance یا توزیع پذیری است. در تئوری CAP مطرح میشود که هر بانک اطلاعاتی خاص، تنها دو مورد از سه مورد مطرح شده را میتواند با هم پوشش دهد.
به این ترتیب بانکهای اطلاعاتی رابطهای عموما دو مورد C و P یا یکپارچگی (Consistency) و partition tolerance یا میزان تحمل تقسیم شدن اطلاعات را ارائه میدهند. اما بانکهای اطلاعاتی NoSQL از این تئوری، تنها دو مورد A و P را پوشش میدهند (دسترسی پذیری و توزیع پذیری مطلوب).
بنابراین مفهومی به نام ACID که در بانکهای اطلاعاتی رابطهای ضامن یکپارچگی اطلاعات آنها است، در دنیای NoSQL وجود خارجی ندارد. کلمه ACID مخفف موارد ذیل است:
Atomicity، Consistency، Isolation و Durability
ACID در بانکهای اطلاعاتی رابطهای تضمین شده است. در این نوع سیستمها، با ایجاد تراکنشها، مباحث ایزوله سازی و یکپارچگی اطلاعات به نحو مطلوبی مدیریت میگردد؛ اما دنیای NoSQL، دسترسی پذیری را به یکپارچگی ترجیح داده است و به همین جهت پیشتر مطرح شد که مفهوم «Eventual consistency یا عاقبت یک دست شدن» در این نوع بانکهای اطلاعاتی در پشت صحنه بکار گرفته میشود. یک مثال دنیای واقعی از عاقبت یک دست شدن اطلاعات را حتما در مباحث DNS مطالعه کردهاید. زمانیکه یک رکورد DNS اضافه میشود یا به روز خواهد شد، اعمال این دستورات در سراسر دنیا به یکباره و همزمان نیست. هرچند اعمال این اطلاعات جدید در یک نود شبکه ممکن است آنی باشد، اما پخش و توزیع آن در سراسر سرورهای DNS دنیا، مدتی زمان خواهد برد (گاهی تا یک روز یا بیشتر).
به همین جهت است که بانکهای اطلاعاتی رابطهای در حجمهای عظیم اطلاعات و تعداد کاربران همزمان بالا، کند عمل میکنند. حجم اطلاعات بالا است، مدتی زمان خواهد برد تا تغییرات اعمال شوند، و چون مفهوم ACID در این نوع بانکهای اطلاعاتی تضمین شده است، کاربران باید مدتی منتظر بمانند و نمونهای از آنها را با dead lockهای شایع، احتمالا پیشتر بررسی یا تجربه کردهاید. در مقابل، بانکهای اطلاعاتی NoSQL بجای یکپارچگی، دسترسی پذیری را اولویت اول خود میدانند و نه یکپارچگی اطلاعات را. در یک بانک اطلاعاتی NoSQL، دستور ثبت اطلاعات دریافت میشود (این مرحله آنی است)، اما اعمال نهایی آن آنی نیست و مدتی زمان خواهد برد تا تمام اطلاعات در کلیه سرورها یک دست شوند.
نحوه مدیریت Indexing اطلاعات در بانکهای اطلاعاتی NoSQL
اغلب بانکهای اطلاعاتی NoSQL تنها بر اساس اطلاعات کلیدهای اصلی جداول آنها index میشوند (البته نام خاصی به نام «جدول»، بسته به نوع بانک اطلاعاتی NoSQL ممکن است متفاوت باشد، اما منظور ظرف دربرگیرنده تعدادی رکورد است در اینجا). این ایندکس نیز از نوع clustered است. به این معنا که اطلاعات به صورت فیزیکی، بر همین مبنا ذخیره و مرتب خواهند شد.
یک مثال: بانک اطلاعاتی NoSQL خاصی به نام Hbase که بر فراز Hadoop distributed file system طراحی شده است، دقیقا به همین روش عمل میکند. این فایل سیستم، تنها از روش Append only برای ذخیره سازی اطلاعات استفاده میکند و در آن مفهوم دسترسی اتفاقی یا random access پیاده سازی نشده است. در این حالت، تمام نوشتنها در بافر، لاگ میشوند و در بازههای زمانی متناوب و مشخصی سبب باز تولید فایلهای موجود و مرتب سازی مجدد آنها از ابتدا خواهند شد. دسترسی به این اطلاعات پس از تکمیل نوشتن، به علت مرتب سازی فیزیکی که صورت گرفته، بسیار سریع است. همچنین مصرف کننده سیستم نیز چون بلافاصله پس از ثبت اطلاعات در بافر سیستم، کنترل را به دست میگیرد، احساس کار با سیستمی را خواهد داشت که بسیار سریع است.
به علاوه Indexهای دیگری نیز وجود دارند که بر اساس کلیدهای اصلی جداول تولید نمیشوند و به آنها ایندکسهای ثانویه یا secondary indexes نیز گفته میشود و تنها تعداد محدودی از بانکهای اطلاعاتی NoSQL از آنها پشتیبانی میکنند. این مساله هم از اینجا ناشی میشود که با توجه به بدون اسکیما بودن جداول بانکهای اطلاعاتی NoSQL، چگونه میتوان اطلاعاتی را ایندکس کرد که ممکن است در رکورد دیگری، ساختار متناظر با آن اصلا وجود خارجی نداشته باشد.
نحوه پردازش Queries در بانکهای اطلاعاتی NoSQL
بانکهای اطلاعاتی NoSQL عموما از زبان کوئری خاصی پشتیبانی نمیکنند. در اینجا باید به اطلاعات به شکل فایلهایی که حاوی رکوردها هستند نگاه کرد. به این ترتیب برای پردازش و یافتن اطلاعات درون این فایلها، نیاز به ایجاد برنامههایی است که این فایلها را گشوده و بر اساس منطق خاصی، اطلاعات مورد نظر را استخراج کنند. گاهی از اوقات زبان SQL نیز پشتیبانی میشود ولی آنچنان عمومیت ندارد. الگوریتمی که در این برنامهها بکار گرفته میشود، Map Reduce نام دارد.
Map Reduce به معنای نوشتن کدی است، با دو تابع. اولین تابع اصطلاحا Map step یا مرحله نگاشت نام دارد. در این مرحله کوئری به قسمتهای کوچکتری خرد شده و بر روی سیستمهای توزیع شده به صورت موازی اجرا میشود. مرحله بعد Reduce step نام دارد که در آن، نتیجه دریافتی حاصل از کوئریهای اجرا شده بر روی سیستمهای مختلف، با هم یکی خواهند شد.
این روش برای نمونه در سیستم Hadoop بسیار مرسوم است. Hadoop دارای یک فایل سیستم توزیع شده است (که پیشتر در مورد آن بحث شد) به همراه یک موتور Map Reduce توکار. همچنین رده دیگری از بانکهای اطلاعاتی NoSQL، اصطلاحا Wide column store نام دارند (مانند Hbase) که عموما به همراه Hadoop بکارگرفته میشوند. موتور Map Reduce متعلق به Hadoop بر روی جداول Hbase اجرا میشوند.
به علاوه Amazon web services دارای سرویسی است به نام Elastic map reduce یا EMR که در حقیقت مجموعهی پردازش ابری است که بر مبنای Hadoop کار میکند. این سرویس قادر است با بانکهای اطلاعاتی NoSQL دیگر و یا حتی بانکهای اطلاعاتی رابطهای نیز کار کند.
بنابراین MapReduce، یک بانک اطلاعاتی نیست؛ بلکه یک روش پردازش اطلاعات است که فایلها را به عنوان ورودی دریافت کرده و یک فایل را به عنوان خروجی تولید میکند. از آنجائیکه بسیاری از بانکهای اطلاعاتی NoSQL کار عمدهاشان، ایجاد و تغییر فایلها است، اغلب جداول اطلاعات آنها ورودی و خروجیهای معتبری برای یک موتور Map reduce به حساب میآیند.
در این بین، افزونهای برای Hadoop به نام Hive طراحی شده است که با ارائه HiveSQL، امکان نوشتن کوئریهایی SQL مانند را بر فراز موتورهای Map reduce ممکن میسازد. این افزونه با Hive tables خاص خودش و یا با Hbase سازگار است.
آشنایی مقدماتی با مفاهیمی مانند الگوهای Sharding و Partitioning در بانکهای اطلاعاتی NoSQL
Sharding (شاردینگ تلفظ میشود) یک الگوی تقسیم اطلاعات بر روی چندین سرور است که اساس توزیع شده بودن بانکهای اطلاعاتی NoSQL را تشکیل میدهد. این نوع تقسیم اطلاعات، از کوئریهایی به نام Fan-out پشتیبانی میکند. به این معنا که شما کوئری خود را به نود اصلی ارسال میکنید و سپس به کمک موتورهای Map reduce، این کوئری بر روی سرورهای مختلف اجرا شده و نتیجه نهایی جمع آوری خواهد شد. به این ترتیب تقسیم اطلاعات، صرفا به معنای قرار دادن یک سری فایل بر روی سرورهای مختلف نیست، بلکه هر کدام از این سرورها به صورت مستقل نیز قابلیت پردازش اطلاعات را دارند.
امکان تکثیر و همچنین replication هر کدام از سرورها نیز وجود دارد که قابلیت بازیابی سریع و مقاومت در برابر خرابیها و مشکلات را افزایش میدهند.
از آنجائیکه Shardها را میتوان در سرورهای بسیار متفاوت و گستردهای از لحاظ جغرافیایی قرار داد، هر Shard میتواند همانند مفاهیم CDN نیز عمل کند؛ به این معنا که میتوان Shard مورد نیاز سروری خاص را در محلی نزدیکتر به او قرار داد. به این ترتیب سرعت عملیات افزایش یافته و همچنین بار شبکه نیز کاهش مییابد.
لیست مشترکات بانکهای اطلاعاتی NoSQL
قبل از اینکه بخواهیم وارد ریز جزئیات بانکهای اطلاعاتی NoSQL شویم، نیاز است لیست و سرفصلی از مفاهیم اصلی و مشترک بین اینگونه بانکهای اطلاعاتی را تدارک ببینیم که شامل موارد ذیل میشود:
الف) Non-Relational یا غیر رابطهای
از کلمه NoSQL عموما اینطور برداشت میشود که در اینجا دیگر خبری از SQL نویسی نیست که در عمل برداشت نادرستی است. شاید جالب باشد که بدانید، تعدادی از بانکهای اطلاعاتی NoSQL از زبان SQL نیز به عنوان اینترفیسی برای نوشتن کوئریهای مرتبط، پشتیبانی میکنند.
کلمه NoSQL بیشتر به Non-Relational یا غیر رابطهای بودن اینگونه بانکهای اطلاعاتی بر میگردد. مباحثی مانند مدلهای دادهای نرمال شده، اتصالات و Join جداول، در دنیای NoSQL وجود خارجی ندارند.
ب) Non-schematized/schema free یا بدون اسکیما
مفهوم مهم و مشترک دیگری که در بین بانکهای اطلاعاتی NoSQL وجود دارد، بدون اسکیما بودن اطلاعات آنها است. به این معنا که با حرکت از رکورد یک به رکورد دو، ممکن است با دو ساختار دادهای متفاوت مواجه شوید.
ج) Eventual consistency یا عاقبت یک دست شدن
عاقبت یک دست شدن، به معنای دریافت دستوری از شما و نحوه پاسخ دادن به آن (یا حتی پاسخ ندادن به آن) از طرف بانک اطلاعاتی NoSQL است. برای مثال، زمانیکه یک رکورد جدید را اضافه میکنید، یا اطلاعات موجودی را به روز رسانی خواهید کرد، اغلب بانکهای اطلاعاتی NoSQL این دستور را بسیار سریع دریافت و پردازش خواهند کرد. اما تفاوت است بین دریافت پیام و پردازش واقعی آن در اینجا.
اکثر بانکهای اطلاعاتی NoSQL، پردازش و اعمال واقعی دستورات دریافتی را با یک تاخیر انجام میدهند. به این ترتیب میتوان خیلی سریع به بانک اطلاعاتی اعلام کرد که چه میخواهیم و بانک اطلاعاتی بلافاصله مجددا کنترل را به شما بازخواهد گرداند. اما اعمال و انتشار واقعی این دستور، مدتی زمان خواهد برد.
د) Open source یا منبع باز بودن
اغلب بانکهای اطلاعاتی NoSQL موجود، منبع باز هستند که علاوه بر بهره بردن از مزایای اینگونه پروژهها، استفاده کنندگان سورس باز دیگری را نیز ترغیب به استفاده از آنها کردهاند.
ه) Distributed یا توزیع شده
هرچند امکان پیاده سازی توزیع شده بانکهای اطلاعاتی رابطهای نیز وجود دارد، اما نیاز به تنظیمات قابل توجهی برای حصول این امر میباشد. در دنیای NoSQL، توزیع شده بودن جزئی از استاندارد تهیه اینگونه بانکهای اطلاعاتی است و بر اساس این مدل ذهنی شکل گرفتهاند. به این معنا که اطلاعات را میتوان بین چندین سیستم تقسیم کرد، که حتی این سیستمها ممکن است فواصل جغرافیایی قابل توجهی نیز با یکدیگر داشته باشند.
و) Web scale یا مناسب برای برنامههای تحت وب پر کاربر
امروزه بسیاری از کمپانیهای بزرگ اینترنتی، برای مدیریت تعداد بالایی از کاربران همزمان خود، مانند فیسبوک، یاهو، گوگل، Linkedin، مایکروسافت و غیره، نیاز به بانکهای اطلاعاتی پیدا کردهاند که باید در مقابل این حجم عظیم درخواستها و همچنین اطلاعاتی که دارند، بسیار بسیار سریع پاسخ دهند. به همین جهت بانکهای اطلاعاتی NoSQL ابداع شدهاند تا بتوان برای این نوع سناریوها پاسخی را ارائه داد.
و نکته مهم دیگر اینجا است که خود این کمپانیهای بزرگ اینترنتی، بزرگترین توسعه دهندههای بانکهای اطلاعاتی NoSQL نیز هستند.
نحوه مدیریت یکپارچگی اطلاعات در بانکهای اطلاعاتی NoSQL
مدیریت یکپارچگی اطلاعات بانکهای اطلاعاتی NoSQL به علت ذات و طراحی توزیع شده آنها، با نحوه مدیریت یکپارچگی اطلاعات بانکهای اطلاعاتی رابطهای متفاوت است. اینجا است که تئوری خاصی به نام CAP مطرح میشود که شامل یکپارچگی یا Consistency به همراه Availability یا دسترسی پذیری (همیشه برقرار بودن) و partition tolerance یا توزیع پذیری است. در تئوری CAP مطرح میشود که هر بانک اطلاعاتی خاص، تنها دو مورد از سه مورد مطرح شده را میتواند با هم پوشش دهد.
به این ترتیب بانکهای اطلاعاتی رابطهای عموما دو مورد C و P یا یکپارچگی (Consistency) و partition tolerance یا میزان تحمل تقسیم شدن اطلاعات را ارائه میدهند. اما بانکهای اطلاعاتی NoSQL از این تئوری، تنها دو مورد A و P را پوشش میدهند (دسترسی پذیری و توزیع پذیری مطلوب).
بنابراین مفهومی به نام ACID که در بانکهای اطلاعاتی رابطهای ضامن یکپارچگی اطلاعات آنها است، در دنیای NoSQL وجود خارجی ندارد. کلمه ACID مخفف موارد ذیل است:
Atomicity، Consistency، Isolation و Durability
ACID در بانکهای اطلاعاتی رابطهای تضمین شده است. در این نوع سیستمها، با ایجاد تراکنشها، مباحث ایزوله سازی و یکپارچگی اطلاعات به نحو مطلوبی مدیریت میگردد؛ اما دنیای NoSQL، دسترسی پذیری را به یکپارچگی ترجیح داده است و به همین جهت پیشتر مطرح شد که مفهوم «Eventual consistency یا عاقبت یک دست شدن» در این نوع بانکهای اطلاعاتی در پشت صحنه بکار گرفته میشود. یک مثال دنیای واقعی از عاقبت یک دست شدن اطلاعات را حتما در مباحث DNS مطالعه کردهاید. زمانیکه یک رکورد DNS اضافه میشود یا به روز خواهد شد، اعمال این دستورات در سراسر دنیا به یکباره و همزمان نیست. هرچند اعمال این اطلاعات جدید در یک نود شبکه ممکن است آنی باشد، اما پخش و توزیع آن در سراسر سرورهای DNS دنیا، مدتی زمان خواهد برد (گاهی تا یک روز یا بیشتر).
به همین جهت است که بانکهای اطلاعاتی رابطهای در حجمهای عظیم اطلاعات و تعداد کاربران همزمان بالا، کند عمل میکنند. حجم اطلاعات بالا است، مدتی زمان خواهد برد تا تغییرات اعمال شوند، و چون مفهوم ACID در این نوع بانکهای اطلاعاتی تضمین شده است، کاربران باید مدتی منتظر بمانند و نمونهای از آنها را با dead lockهای شایع، احتمالا پیشتر بررسی یا تجربه کردهاید. در مقابل، بانکهای اطلاعاتی NoSQL بجای یکپارچگی، دسترسی پذیری را اولویت اول خود میدانند و نه یکپارچگی اطلاعات را. در یک بانک اطلاعاتی NoSQL، دستور ثبت اطلاعات دریافت میشود (این مرحله آنی است)، اما اعمال نهایی آن آنی نیست و مدتی زمان خواهد برد تا تمام اطلاعات در کلیه سرورها یک دست شوند.
نحوه مدیریت Indexing اطلاعات در بانکهای اطلاعاتی NoSQL
اغلب بانکهای اطلاعاتی NoSQL تنها بر اساس اطلاعات کلیدهای اصلی جداول آنها index میشوند (البته نام خاصی به نام «جدول»، بسته به نوع بانک اطلاعاتی NoSQL ممکن است متفاوت باشد، اما منظور ظرف دربرگیرنده تعدادی رکورد است در اینجا). این ایندکس نیز از نوع clustered است. به این معنا که اطلاعات به صورت فیزیکی، بر همین مبنا ذخیره و مرتب خواهند شد.
یک مثال: بانک اطلاعاتی NoSQL خاصی به نام Hbase که بر فراز Hadoop distributed file system طراحی شده است، دقیقا به همین روش عمل میکند. این فایل سیستم، تنها از روش Append only برای ذخیره سازی اطلاعات استفاده میکند و در آن مفهوم دسترسی اتفاقی یا random access پیاده سازی نشده است. در این حالت، تمام نوشتنها در بافر، لاگ میشوند و در بازههای زمانی متناوب و مشخصی سبب باز تولید فایلهای موجود و مرتب سازی مجدد آنها از ابتدا خواهند شد. دسترسی به این اطلاعات پس از تکمیل نوشتن، به علت مرتب سازی فیزیکی که صورت گرفته، بسیار سریع است. همچنین مصرف کننده سیستم نیز چون بلافاصله پس از ثبت اطلاعات در بافر سیستم، کنترل را به دست میگیرد، احساس کار با سیستمی را خواهد داشت که بسیار سریع است.
به علاوه Indexهای دیگری نیز وجود دارند که بر اساس کلیدهای اصلی جداول تولید نمیشوند و به آنها ایندکسهای ثانویه یا secondary indexes نیز گفته میشود و تنها تعداد محدودی از بانکهای اطلاعاتی NoSQL از آنها پشتیبانی میکنند. این مساله هم از اینجا ناشی میشود که با توجه به بدون اسکیما بودن جداول بانکهای اطلاعاتی NoSQL، چگونه میتوان اطلاعاتی را ایندکس کرد که ممکن است در رکورد دیگری، ساختار متناظر با آن اصلا وجود خارجی نداشته باشد.
نحوه پردازش Queries در بانکهای اطلاعاتی NoSQL
بانکهای اطلاعاتی NoSQL عموما از زبان کوئری خاصی پشتیبانی نمیکنند. در اینجا باید به اطلاعات به شکل فایلهایی که حاوی رکوردها هستند نگاه کرد. به این ترتیب برای پردازش و یافتن اطلاعات درون این فایلها، نیاز به ایجاد برنامههایی است که این فایلها را گشوده و بر اساس منطق خاصی، اطلاعات مورد نظر را استخراج کنند. گاهی از اوقات زبان SQL نیز پشتیبانی میشود ولی آنچنان عمومیت ندارد. الگوریتمی که در این برنامهها بکار گرفته میشود، Map Reduce نام دارد.
Map Reduce به معنای نوشتن کدی است، با دو تابع. اولین تابع اصطلاحا Map step یا مرحله نگاشت نام دارد. در این مرحله کوئری به قسمتهای کوچکتری خرد شده و بر روی سیستمهای توزیع شده به صورت موازی اجرا میشود. مرحله بعد Reduce step نام دارد که در آن، نتیجه دریافتی حاصل از کوئریهای اجرا شده بر روی سیستمهای مختلف، با هم یکی خواهند شد.
این روش برای نمونه در سیستم Hadoop بسیار مرسوم است. Hadoop دارای یک فایل سیستم توزیع شده است (که پیشتر در مورد آن بحث شد) به همراه یک موتور Map Reduce توکار. همچنین رده دیگری از بانکهای اطلاعاتی NoSQL، اصطلاحا Wide column store نام دارند (مانند Hbase) که عموما به همراه Hadoop بکارگرفته میشوند. موتور Map Reduce متعلق به Hadoop بر روی جداول Hbase اجرا میشوند.
به علاوه Amazon web services دارای سرویسی است به نام Elastic map reduce یا EMR که در حقیقت مجموعهی پردازش ابری است که بر مبنای Hadoop کار میکند. این سرویس قادر است با بانکهای اطلاعاتی NoSQL دیگر و یا حتی بانکهای اطلاعاتی رابطهای نیز کار کند.
بنابراین MapReduce، یک بانک اطلاعاتی نیست؛ بلکه یک روش پردازش اطلاعات است که فایلها را به عنوان ورودی دریافت کرده و یک فایل را به عنوان خروجی تولید میکند. از آنجائیکه بسیاری از بانکهای اطلاعاتی NoSQL کار عمدهاشان، ایجاد و تغییر فایلها است، اغلب جداول اطلاعات آنها ورودی و خروجیهای معتبری برای یک موتور Map reduce به حساب میآیند.
در این بین، افزونهای برای Hadoop به نام Hive طراحی شده است که با ارائه HiveSQL، امکان نوشتن کوئریهایی SQL مانند را بر فراز موتورهای Map reduce ممکن میسازد. این افزونه با Hive tables خاص خودش و یا با Hbase سازگار است.
آشنایی مقدماتی با مفاهیمی مانند الگوهای Sharding و Partitioning در بانکهای اطلاعاتی NoSQL
Sharding (شاردینگ تلفظ میشود) یک الگوی تقسیم اطلاعات بر روی چندین سرور است که اساس توزیع شده بودن بانکهای اطلاعاتی NoSQL را تشکیل میدهد. این نوع تقسیم اطلاعات، از کوئریهایی به نام Fan-out پشتیبانی میکند. به این معنا که شما کوئری خود را به نود اصلی ارسال میکنید و سپس به کمک موتورهای Map reduce، این کوئری بر روی سرورهای مختلف اجرا شده و نتیجه نهایی جمع آوری خواهد شد. به این ترتیب تقسیم اطلاعات، صرفا به معنای قرار دادن یک سری فایل بر روی سرورهای مختلف نیست، بلکه هر کدام از این سرورها به صورت مستقل نیز قابلیت پردازش اطلاعات را دارند.
امکان تکثیر و همچنین replication هر کدام از سرورها نیز وجود دارد که قابلیت بازیابی سریع و مقاومت در برابر خرابیها و مشکلات را افزایش میدهند.
از آنجائیکه Shardها را میتوان در سرورهای بسیار متفاوت و گستردهای از لحاظ جغرافیایی قرار داد، هر Shard میتواند همانند مفاهیم CDN نیز عمل کند؛ به این معنا که میتوان Shard مورد نیاز سروری خاص را در محلی نزدیکتر به او قرار داد. به این ترتیب سرعت عملیات افزایش یافته و همچنین بار شبکه نیز کاهش مییابد.
امروزه بازار برنامههای تماما 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 را جهت افزودن امکانات پلاگین این گونه تغییر دهید :
نکته : فایل fa.js که جهت استفاده از زبان فارسی در اینترفیس آپلود فایلها میباشد، که وجود آن در آدرس واضح میباشد.
سپس به فایل Views->Home->Index.cshtml بروید و آن را این گونه دوباره نویسی کنید :
توضیحات و نکات :
- جهت آپلود فایلها تگ enctype = "multipart/form-data" را فراموش نکنید.
- در قسمت مقداردهی به ویژگیهای Plupload ، قسمت runtime به صورت ترتیبی کار میکند لذا اگر اولی پشتیبانی نشود سراغ دومی میرود و اگر دومی نشود سومی و ... در صفحهی اول سایت PlUpload ، موارد پشتیبانی شده توسط تکنولوژیها آورده شده است لذا این ترتیب را ترتیب مناسبی میبینم و اگر اولین مورد html5 باشد امکان Drag&Drop وجود خواهد داشت.
خود سایت PlUpload داکیومنت خیلی خوبی جهت توضیح موارد مختلف دارد لذا توضیح دوباره لازم نیست.
همان طور که در ویژگی url مشاهده میکنید به کنترلر Home و اکشن متود Upload اشاره شده است که طرز کار به این گونه است که هر بار که یک فایل آپلود میشود درخواستی به این آدرس و محتوای فایل در قسمت Request.Files ارسال میشود و همین طور نام فایل که unique ارسال میشود و chunk که تیکههای فایل است(پست میشود).
پس اکشنی با نام Upload در کنترلر HomeController بسازید :
توضیحات : ابتدا فایل مورد نظر از قسمت Request.Files واکشی میشود و سپس فایل را در پوشه App_Data ذخیره میکند. (یکی از چندین روش ذخیره سازی که مطالعه در این قسمت به خواننده واگذار میشود.)
حال برنامه را اجرا کنید و از این ابزار لذت ببرید:)
در این میان یکی از دغدغههای توسعه دهندگان وب ، آپلود فایلها به صورت آنی (مثل 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"); }
حال برنامه را اجرا کنید و از این ابزار لذت ببرید:)
نکته : قسمت فارسی ساز اونو تغییر دادم چون که ترجمهی فارسی خودش یه سری نقایصی داشت که گویا از کار با google translate به وجود اومده بود!
نظر من Native, به این دلیل که :1- گوگل به طور رسمی ازش پشتیبانی میکنه پس خیلی سریع به آخرین تغییرات و apiهای مرتبط دسترسی وجود داره 2- توسعه بصورت رایگان هست . 3- کامیونیتی بزرگتری برای اون وجود داره ، حین برنامه نویسی احساس تنهایی نمیکنم :) 4- قدمت بیشتری داره بنابرین بسیاری از سوالات و مشکلاتی که حین توسعه پیش میاد ، قبلا برای سایر دولوپرها پیش اومده و با یه سرچ کوچیک میشه به جواب رسید 5- یادگیری یه زبان و پلتفرم دیگه برام لذت بخش هست 6- روشهای native به اصطلاح پختهتر و stableتر هستند . 7- و شاید بزرگترین دلیل اینکه خیالم راحته ، از این نظر که میدونم ابزاری که استفاده میکنم به احتمال قریب به یقین تا چند سال آینده تغییر چندانی نخواهد کرد ، با خاطر آسوده فقط به موضوع فنی که یه برنامه نویس باید مسلط باشه تمرکز میکنم و نگرانی ندارم که ممکنه ظرف مدت زمان کوتاهی مجبور شم سوئیچ کنم به یک محیط و ابزار دیگه .
دلایل ریزتر دیگه ای هم برای من وجود داره که به اندازه دلایل سبعه فوق (!) اهم نیستند .
نظرات مطالب
استفاده از API ترجمه گوگل
از بخش برنامه نویسی آن که جای تشکر بسیار داره و عالی بود که بگذریم. یک بار هم نشده با این مترجم گوگل کار کنم و ترجمه خوب بگیرم.