مقدمه

در درس گذشته با معماری کلی ASP.NET Core آشنا شدیم و دیدیم که این فریم‌ورک چندین مدل برنامه‌نویسی را برای ساخت اپلیکیشن‌های وب ارائه می‌دهد. در این درس، ما بر روی یکی از ساده‌ترین و در عین حال قدرتمندترین این مدل‌ها تمرکز خواهیم کرد: Razor Pages. Razor Pages یک مدل برنامه‌نویسی صفحه‌محور (page-centric) است که در آن، هر صفحه‌ی وب از دو فایل مرتبط تشکیل شده است: یک فایل برای نمایش (HTML و سینتکس Razor) و یک فایل برای منطق (C#).

این رویکرد، ساخت وب‌سایت‌های داده‌محور را بسیار ساده می‌کند، زیرا منطق و نمایش مربوط به یک صفحه‌ی خاص، در کنار یکدیگر قرار دارند و این کار باعث سازماندهی بهتر کد می‌شود. این مدل به خصوص برای برنامه‌نویسانی که از مدل‌های سنتی‌تری مانند Web Forms یا PHP می‌آیند، بسیار شهودی و آشناست.

ساختار یک صفحه‌ی Razor

هر صفحه‌ی Razor در پوشه‌ی Pages پروژه قرار گرفته و از دو فایل تشکیل شده است:

  1. فایل .cshtml: این فایل حاوی کدهای HTML و سینتکس Razor برای تولید داینامیک رابط کاربری است.
  2. فایل .cshtml.cs: این فایل که به آن "کد پشت صحنه" (code-behind) گفته می‌شود، حاوی یک کلاس C# است که از PageModel ارث‌بری می‌کند. تمام منطق مربوط به آن صفحه، مانند دریافت داده از پایگاه داده و مدیریت درخواست‌های کاربر، در این کلاس قرار می‌گیرد.

برای مثال، یک صفحه‌ی Index.cshtml یک فایل Index.cshtml.cs متناظر با خود دارد.

مدل صفحه (PageModel) و هندلرهای آن

کلاس PageModel قلب منطقی یک صفحه‌ی Razor است. این کلاس می‌تواند شامل پراپرتی‌هایی برای نگهداری داده و متدهایی به نام هندلر (Handler) برای پاسخ به درخواست‌های HTTP باشد.

هندلرها متدهایی هستند که نام آن‌ها با الگوی On[Verb][Async] مطابقت دارد.

  • OnGet یا OnGetAsync: این هندلر زمانی اجرا می‌شود که صفحه با یک درخواست HTTP GET فراخوانی شود (مثلاً زمانی که کاربر برای اولین بار به آن صفحه مراجعه می‌کند). این هندلر معمولاً برای خواندن داده‌ها از پایگاه داده و آماده‌سازی آن‌ها برای نمایش استفاده می‌شود.
  • OnPost یا OnPostAsync: این هندلر زمانی اجرا می‌شود که یک فرم (form) از داخل صفحه با متد POST ارسال شود. این هندلر برای پردازش داده‌های ورودی کاربر (مانند ایجاد یا ویرایش یک رکورد) به کار می‌رود.

یک مثال عملی: نمایش لیست فیلم‌ها

بیایید با استفاده از مدل Movie و WebAppDbContext که در درس‌های قبل ساختیم، یک صفحه برای نمایش لیست فیلم‌ها ایجاد کنیم.

قدم اول: تزریق DbContext

ابتدا باید WebAppDbContext را به کلاس PageModel خود تزریق (inject) کنیم تا بتوانیم به پایگاه داده دسترسی داشته باشیم.

Copy Icon Index.cshtml.cs
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;

public class IndexModel : PageModel
{
    private readonly WebAppDbContext _context;

    // The DbContext is injected via the constructor.
    public IndexModel(WebAppDbContext context)
    {
        _context = context;
    }

    public IList<Movie> Movies { get; set; }

    // This handler is called on an HTTP GET request.
    public async Task OnGetAsync()
    {
        Movies = await _context.Movie.ToListAsync();
    }
}

در این کد، ما WebAppDbContext را از طریق سازنده دریافت کرده و در یک فیلد خصوصی ذخیره می‌کنیم. سپس در هندلر OnGetAsync، تمام فیلم‌ها را از پایگاه داده خوانده و در پراپرتی عمومی Movies قرار می‌دهیم.

قدم دوم: نمایش داده‌ها در فایل Razor

اکنون در فایل Index.cshtml، می‌توانیم به پراپرتی Movies که در PageModel تعریف شده، دسترسی پیدا کرده و داده‌های آن را در یک جدول HTML نمایش دهیم.

Copy Icon Index.cshtml
@page
@model IndexModel

<h1>Movie List</h1>

<table class="table">
    <thead>
        <tr>
            <th>Title</th>
            <th>Release Date</th>
        </tr>
    </thead>
    <tbody>
        <-- We can access the Model property to get data from the PageModel -->
        @foreach (var movie in Model.Movies)
        {
            <tr>
                <td>@movie.Title</td>
                <td>@movie.ReleaseDate.ToShortDateString()</td>
            </tr>
        }
    </tbody>
</table>

در اینجا، @page یک دایرکتیو Razor است که این فایل را به عنوان یک صفحه‌ی قابل مسیریابی مشخص می‌کند. @model IndexModel به صفحه می‌گوید که مدل داده‌ی آن، یک نمونه از کلاس IndexModel است. سپس با استفاده از Model.Movies، به لیستی که در OnGetAsync پر کرده بودیم، دسترسی پیدا کرده و با یک حلقه‌ی foreach آن را نمایش می‌دهیم. علامت @ کاراکتر جادویی Razor است که به ما اجازه می‌دهد کد C# را مستقیماً در داخل HTML بنویسیم.