ساختن یک وب اپلیکیشن با استفاده از ASP.NET Core Blazor
در این پست از وبسایت پرووید، در رابطه با ساختن یک وب اپلیکیشن با استفاده از ASP.NET Core Blazor صحبت خواهیم کرد. به ادامه ی مطلب بروید.
در این قسمت از وبسایت پرووید یک آموزش متنی در رابطه با ساختن یک Web Application با استفاده از فریم ورک Blazor را برای شما در نظر گرفته ایم. پیش از این نیز آموزش های متعددی در رابطه با همین موضوع بر روی وبسایت پرووید منتشر شدهاند. در ابتدا در رابطه با اینکه Blazor چیست صحبت خواهیم کرد.
Blazor چیست؟
Framework Blazor یک Framework برای ساختن وب اپلیکیشن های تک صفحه ای و یا اصطلاحاً Single-Page Application می باشد که با استفاده از آن می توانید کدهای سی شارپ و HTML را در کنار هم قرار بدهید تا در سمت Client و یا اصطلاحاً Client-Side اجرا بشوند. این نوع از برنامه ها بسیار شبیه به Razor Pages Application ها می باشند. کد نوشته شده به زبان سی شارپ به یک استاندارد به نام WebAssembly کامپایل خواهد شد که به شما اجازه میدهد از قابلیتهای تمامی مرورگرهای وب امروزی استفاده کنید. در واقع با استفاده کردن از Framework Blazor به سادگی می توانیم اپلیکیشن های Client-Side که از سی شارپ و .NET Core استفاده می کنند را ایجاد کنیم. استفاده کردن از Framework Blazor برای تمامی دوستانی که امکان استفاده کردن از زبان JavaScript برای ساختن برنامه های Client-Side را ندارند بسیار مناسب می باشد؛ به عبارت دیگر با استفاده کردن از Blazor شما دیگر نیازی به استفاده کردن از زبان JavaScript برای نوشتن کدهای سمت Client نیستید و به راحتی می توانید با استفاده از سی شارپ و همچنین .NET Core برنامه هایی بنویسید که کدهای سی شارپ را در سمت Client و در مرورگر کاربر اجرا می کنند.
راه اندازی فریم ورک Blazor
در Visual Studio 2019 امکان استفاده از Framework Blazor وجود ندارد. بنابراین باید اقدام به نصب کردن SDK ها و Template های مناسب کنید. جزئیات مربوط به انجام این کار در مستندات Microsoft قرار گرفته است که در صورت نیاز می توانید به آنها رجوع کنید و فریم ورک Blazor را نصب نمایید.
بررسی اپلیکیشن این آموزش
در این آموزش قرار است که یک اپلیکیشن نمونه را برای نشان دادن نحوه استفاده کردن از فریم ورک Blazor به شما ارائه بدهیم. ضمناً این اپلیکیشن در GitHub قرار گرفته شده است و در صورت نیاز می توانید آن را نیز اضافه کنید. تصویری که در قسمت زیر مشاهده می کنید برخی از فایل های موجود در یک برنامه ساده Blazor می باشد که در رابطه با آنها صحبت خواهیم کرد.
در ابتدا فولدرهای Dependencies و Properties و wwwroot را داریم که شبیه به یک اپلیکیشن معمولی ASP.NET Core می باشند.
- فولدر Pages شامل صفحاتی است که نهایتاً برنامه را تشکیل میدهند که شبیه به یک اپلیکیشن Razor Page عمل میکند.
- فولدر Shared حاوی فایل های Layout می باشد که در سرتاسر برنامه مورد استفاده قرار میگیرند.
- فایل ViewImports.cshtml برای Import کردن Namespace ها به درون دیگر فایل های cshtml مورد استفاده قرار میگیرد.
- فایل Program.cs برای ساختن Hosting Environment مربوط به ASP.NET Core مورد استفاده قرار می گیرد.
- فایل Startup.cs برای ساختن تنظیمات مربوط به پروژه Blazor و Dependency های آن مورد استفاده قرار می گیرد.
- نهایتاً فایل App.cshtml شامل تنها فایلی است که مربوط به برنامه Blazor می باشد.
برنامه هایی که با فریم ورک Blazor ساخته می شوند به طور پیش فرض دارای یک Client-Side Router می باشند که برای اکثر کاربردهای معمولی نیاز را رفع می کند؛ البته این Router به مراتب از Router فریم ورک Angular ساده تر می باشد اما در این مثال و در بسیاری از برنامههای دیگر جوابگوی نیاز ما خواهد بود. ضمناً در بررسی مسیریابی (Routing) در فریم ورک AngularJS در این رابطه بیشتر صحبت کرده ایم. اگر برنامه نمونهای که دانلود کرده اید را اجرا کنید صفحه زیر را مشاهده خواهید کرد.
این برنامه به طور کامل در سمت Client و یا اصطلاحاً Client-Side می باشد که کدهای سی شارپ را به WebAssembly کامپایل می کند. حال اگر سعی کنید که از صفحه Counter به صفحه Fetch Data بروید، خواهید دید که عملکرد برنامه چقدر سریع اتفاق می افتد و هیچ نیازی به Refresh شدن صفحه نیست. این برنامه نمونهای است که Visual Studio بر اساس الگوی و یا Template فریم ورک Blazor برای ما ایجاد میکند. حال قرار است که این برنامه را طوری تغییر بدهیم تا مفاهیم مربوط به فریم ورک Blazor را بهتر درک کنیم.
اضافه کردن یک To-Do List
قرار است که یک صفحه جدید به برنامه نمونهای که تا به اینجای کار آن را دیدید اضافه کنیم تا یک To-Do List بسیار ساده را ایجاد نماییم. منظور از To-Do List، لیست کارهایی است که به صورت روزمره قرار است انجام بدهیم. برای پیادهسازی این موضوع به سه بخش نیاز داریم:
- مجموعه ای از داده ها که در ابتدای کار در صفحه برنامه بارگذاری و یا Load می شوند.
- یک صفحه جدید که قسمت To-Do List را میزبانی و یا اصطلاحاً Host مینماید.
- تعدادی از توابع که قرار است بر روی آن صفحه عملیات اضافه کردن، حذف کردن و دیگر موارد مربوط به آیتم های To-Do List را انجام بدهند.
در ابتدا به منظور اضافه کردن داده های نمونه در برنامه در فولدر wwwroot یک زیرفولدر به نام SampleData خواهید دید. اگر این فولدر وجود ندارد آن را ایجاد کنید و سپس یک فایل JSON با نام Todoitems.json را به این فولدر اضافه کنید و کدی که در قسمت زیر مشاهده میکنید را در آن قرار بدهید.
[ { "id": "f0dcda47-1f23-4538-92e0-a47dcdcc7850", "description": "Read this tutorial", "iscomplete": false, "datecreated": "2019-04-11" }, { "id": "d21b0f7e-a5a9-45ee-ad9b-eafd911e22fa", "description": "Build my own Blazor app", "iscomplete": false, "datecreated": "2019-04-11" } ]
در ادامه نیاز به ساختن یک صفحه به نام ToDo.cshtml داریم. برای انجام این کار بر روی فولدر Pages راست کلیک کرده و سپس گزینه Add و پس از آن Razor Page را انتخاب کنید. اگر در روند انجام این کار با مشکل روبرو شدید و یا نتوانستید این آیتم یعنی Razor Page را پیدا کنید، میتوانید از یکی از صفحاتی که از قبل ساخته شده است یک کپی گرفته و سپس آن را Paste کنید. به هر حال کد زیر را در صفحه مورد نظر قرار بدهید.
@page "/todo" @inject HttpClient Http <h1>To-Do List</h1>
حال در رابطه با کدهای موجود در این صفحه صحبت خواهیم کرد. اولین دستور موجود در این صفحه دستور @page می باشد که به ASP.NET Core میگوید که این یک Razor Page است و همچنین Route پیش فرض مربوط به این صفحه را تنظیم میکند. در این مثال Route را به صورت نسبی و یا اصطلاحاً Relative و به صورت /todo تنظیم کردهایم. این پارامتر هم میتواند در قالب یک Route نسبی و یا یک Route مطلق تنظیم شود. منظور از Route نسبی همان Relative Route و منظور از Route مطلق Absolute Route میباشد. در زمان استفاده کردن از Absolute Route می توانیم چیزی شبیه به /Path/To/Page را تنظیم کنیم. علاوه بر این می توانیم از چندین دستور @page برای چندین Route استفاده نماییم.
دستور @inject به Blazor میگوید که از Dependency Injection (DI) برای تزریق کلاس HttpClient به درون این صفحه استفاده کند. در رابطه با تزریق وابستگی از تکنیک تزریق وابستگی (Dependency Injection) در برنامه نویسی شی گرا استفاده کنید. از کلاس HttpClient برای خواندن داده های JSON که در قبل ایجاد کردیم استفاده خواهیم کرد.
حال که صفحه مورد نظر را ایجاد کردیم باید بتوانیم دادههایی را خوانده و در آن نشان بدهیم. برای انجام این کار یک کلاس سی شارپ که نمایانگر عناصر لیست To-Do میباشد را ایجاد خواهیم کرد. علاوه بر این یک متد برای بارگذاری کردن داده ها خواهیم نوشت. به این منظور از دستور از @functions در همین صفحه شبیه به کد زیر استفاده خواهیم کرد.
@functions{ IList<ToDoItem> items = new List<ToDoItem>(); protected override async Task OnInitAsync() { items = await Http.GetJsonAsync<List<ToDoItem>>("sample-data/todoitems.json"); } class ToDoItem { public Guid ID { get; set; } public string Description { get; set; } public bool IsComplete { get; set; } public DateTime DateCreated { get; set; } } }
نکته بسیار مهم در این کد استفاده از متد OnInitAsync است. این متد زمانی که صفحه بارگذاری می شود و در مرورگر نشان داده میشود، اجرا خواهد شد. در پیادهسازی انجام شده برای این متد داده های JSON خوانده شده و سپس به Object هایی از کلاس ToDoItem تبدیل میشود. قدم بعدی اضافه کردن کدهای HTML مناسب برای نشان دادن یک جدول از ToDoItem ها می باشد. این موضوع در کد زیر نشان داده شده است.
@if (items == null) { <p><em>Loading...</em></p> } else if (!items.Any()) { <p><em>No ToDo items exist. Please add some.</em></p> } else { <table class="table"> <thead> <tr> <th>Date</th> <th>Description</th> <th>Is Complete</th> </tr> </thead> <tbody> @foreach (var item in items) { <tr> <td>@item.DateCreated</td> <td>@item.Description</td> <td>@item.IsComplete</td> </tr> } </tbody> </table> }
در کدی که در قسمت بالا مشاهده می کنید به دستور @If دقت کنید. در این دستور List<ToDo Item> را چک می کنیم. اگر این Object مقدار Null داشته باشد؛ یعنی هنوز در آن داده ای قرار نگرفته است. پس باید یک خطای مناسب در صفحه نشان داده شود؛ اما اگر List<ToDo Item> خالی باشد یک خطای متفاوت دیگر نشان خواهیم داد و نهایتاً اگر این Object خالی نباشد داده ها را در قالب یک جدول نشان خواهیم داد. آخرین چیزی که برای استفاده کردن از این صفحه باید انجام بدهیم اضافه کردن یک عنصر جدید برای انجام Navigation به این صفحه می باشد. در فایل NavMenu.cshtml کدی که در قسمت زیر مشاهده میکنید را قرار بدهید.
<div class="@NavMenuCssClass" onclick="@ToggleNavMenu"> <ul class="nav flex-column"> <li class="nav-item px-3"> <NavLink class="nav-link" href="" Match="NavLinkMatch.All"> <span class="oi oi-home" aria-hidden="true"></span> Home </NavLink> </li> <li class="nav-item px-3"> <NavLink class="nav-link" href="counter"> <span class="oi oi-plus" aria-hidden="true"></span> Counter </NavLink> </li> <li class="nav-item px-3"> <!-- here's the new item --> <NavLink class="nav-link" href="todo"> <span class="oi oi-list" aria-hidden="true"></span> To-Do </NavLink> </li> <li class="nav-item px-3"> <NavLink class="nav-link" href="fetchdata"> <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data </NavLink> </li> </ul> </div>
حال با اجرا کردن برنامه می توانیم صفحه مورد نظر را ببینیم. این موضوع در تصویر زیر نشان داده شده است.
پس تا به اینجای کار ما توانستیم ToDo Item ها را از یک فایل JSON خوانده و در صفحه نشان بدهیم. حال میخواهیم در همین صفحه اقدام به اضافه کردن امکان درج، حذف و همچنین تغییر دادن ظاهر آیتم ها کنیم.
اضافه کردن یک ToDoItem جدید به لیست
به منظور اضافه کردن یک ToDoItem به لیستی که در برنامه وجود دارد، باید بتوانیم یک متد دیگر اضافه کنیم. برای انجام این کار باری دیگر از دستور @functions برای ایجاد کردن یک متد به منظور افزودن عناصر جدید استفاده می کنیم. این موضوع در قسمت زیر نشان داده شده است.
@if (items == null) { <p><em>Loading...</em></p> } else if (!items.Any()) { <p><em>No ToDo items exist. Please add some.</em></p> } else { <table class="table"> ... </table> } @if (items != null) //Here's the new input { <input placeholder="A new ToDo item" bind="@newItem" /> <button onclick="@AddTodo">Create</button> }
در کدی که در قسمت بالا مشاهده می کنید از یک Attribute به نام Bind استفاده کردهایم. این Attribute یکی از قابلیتهای ASP.NET Core می باشد که با استفاده از آن می توانیم HTML Input ها را به متغیرهایی که بر روی Page تعریف شده اند، اصطلاحاً Bind کنیم. به طور مشابه ASP.NET Core اجازه می دهد تا رویدادهایی از قبیل onClick را به متدهایی اصطلاحاً Bind کنیم. این موضوع در یک Button به نام Create اتفاق افتاده است. حال باید یک متد جدید با نام AddToDo را شبیه به کد زیر را اضافه کنیم.
@functions{ IList<ToDoItem> items = new List<ToDoItem>(); private string newItem; ... /// <summary> /// This method adds a new ToDo item. /// </summary> private void AddTodo() { if (!string.IsNullOrWhiteSpace(newItem)) { items.Add(new ToDoItem() { DateCreated = DateTime.Now, Description = newItem, ID = Guid.NewGuid() }); newItem = string.Empty; //We need to reset this string, otherwise the text box will still contain the value typed in. } } ... }
با این متد و انجام یک اعتبار سنجی و یا Validation ساده و همچنین Bind کردن رویداد onClick مربوط به این دکمه به متد جدیدی که ایجاد کردهایم میتوانیم یک ToDoItem جدید را اضافه کنیم. با اجرا کردن برنامه صفحه زیر را مشاهده خواهید کرد که با استفاده از آن می توانید یک عنصر جدید را به لیست اضافه کنید.
حذف کردن ToDoItem
برای حذف کردن ToDoItem ها نیز ابتدا یک متد با نام Remove را ایجاد خواهیم کرد. علاوه بر این جدولی که با استفاده از HTML ایجاد کرده ایم، شبیه به کد زیر تغییر خواهد کرد.
<table class="table"> <thead> <tr> <th>Remove</th> <th>Date</th> <th>Description</th> <th>Is Complete</th> </tr> </thead> <tbody> @foreach (var item in items) { <tr> <td><button onclick="@(() => RemoveTodo(item.ID))"><i class="oi oi-trash"></i></button></td> <td>@item.DateCreated</td> <td>@item.Description</td> <td>@item.IsComplete</td> </tr> } </tbody> </table>
حال رویداد onClick مربوط به Button که در HTML تعریف شده است را با یک متد به نام RemoveToDo مرتبط می کنیم. این متد در قسمت زیر نشان داده شده است.
@functions{ IList<ToDoItem> items = new List<ToDoItem>(); ... private void RemoveTodo(Guid id) { items.Remove(items.First(x => x.ID == id)); } ... }
فراموش نکنید که در یک برنامه واقعی باید پس از حذف شدن یک عنصر از لیست این تغییرات را در بانک اطلاعاتی ذخیره کنید.
پیاده سازی کردن تغییر حالت ToDoItem ها
آخرین قابلیتی که به برنامه اضافه می کنیم برای تغییر دادن ظاهر عناصری است که در لیست نشان داده شده است. در کلاس ToDoItem یک Property به نام IsComplete قرار داده شده است. علاوه بر این جدولی که در HTML ایجاد کردیم و توابع سی شارپ شبیه به کدهای زیر تغییر خواهند کرد.
<table class="table"> <thead> <tr> <th>Remove</th> <th>Date</th> <th>Description</th> <th>Is Complete</th> </tr> </thead> <tbody> @foreach (var item in items) { <tr> <td><button onclick="@(() => RemoveTodo(item.ID))"><i class="oi oi-trash"></i></button></td> <td>@item.DateCreated</td> <td>@item.Description</td> <td><input type=checkbox onchange="@(() => ToggleToDo(item.ID))" /> @item.IsComplete</td> </tr> } </tbody> </table>
@functions{ IList<ToDoItem> items = new List<ToDoItem>(); private string newItem; ... private void ToggleToDo(Guid id) { //First find the item var todo = items.First(x => x.ID == id); todo.IsComplete = !todo.IsComplete; } ... }
حال اگر برنامه را اجرا کنید خواهید دید که میتوانید علاوه بر حذف کردن و اضافه کردن عناصر جدید آنها را در لیست مورد نظر تغییر شکل داده و به حالت کامل شده تنظیم کنید.
جمع بندی
امیدواریم که این آموزش از وبسایت پرووید مورد توجه تمامی دوستان قرار گرفته باشد. در این آموزش یاد گرفتیم که فریم ورک Blazor یک فریم ورک ساخت اپلیکیشن های Single-Page و یا تک صفحه ای است که اجازه میدهد کدهای سی شارپ در سمت Client و یا Client-Side اجرا بشود. رفتار Blazor و اپلیکیشن هایی که با Blazor ساخته می شوند بسیار شبیه به اپلیکیشن های Razor Page می باشند. ضمنا پروژه معمولی و ساده ای که در این آموزش بررسی شد اپلیکیشن کار کردن با یک ToDo List میباشد که از یک فایل JSON به عنوان Data Source استفاده کرد و توانست عناصر جدید را اضافه کند، عناصر از قبل موجود را حذف کند و یا عناصر را به حالت کامل شده تغییر شکل بدهد. تمامی این قابلیت ها در سمت Client و یا Client-Side رخ خواهد داد. ضمنا در پایان از شما دعوت میکنیم که از دیگر آموزش های وب سایت پرووید در رابطه با فریم ورک Blazor استفاده نمایید.