مقدمه

در درس‌های گذشته، با استفاده از ابزارهای Scaffolding، صفحات CRUD را برای موجودیت Movie خود ایجاد کردیم و دیدیم که چگونه منطق مربوط به هر صفحه در کلاس PageModel قرار می‌گیرد. اما یک اپلیکیشن وب چگونه داده‌ها را از کاربر دریافت می‌کند؟ چگونه مقادیر وارد شده در یک فرم یا پارامترهای موجود در URL به دست کد C# ما در سمت سرور می‌رسد؟

ASP.NET Core یک سیستم قدرتمند و انعطاف‌پذیر برای اتصال مدل (Model Binding) فراهم می‌کند. این سیستم به طور خودکار داده‌های ورودی از درخواست HTTP را استخراج کرده و آن‌ها را به پارامترهای متدهای هندلر (OnGet, OnPost) یا پراپرتی‌های کلاس PageModel ما متصل می‌کند. در این درس، با دو روش اصلی دریافت داده از کاربر آشنا می‌شویم: دریافت داده از مسیر URL و دریافت داده از فرم‌های HTML.

دریافت داده از مسیر (Routing)

یکی از راه‌های رایج برای ارسال داده به سرور، قرار دادن آن در خود URL است. این روش معمولاً برای ارسال شناسه‌ها یا پارامترهای ساده در درخواست‌های HTTP GET به کار می‌رود. Razor Pages از یک سیستم مسیریابی مبتنی بر قرارداد استفاده می‌کند که به ما اجازه می‌دهد پارامترها را به سادگی به عنوان بخشی از مسیر تعریف کنیم.

برای مثال، صفحه‌ی Details.cshtml که توسط Scaffolding ایجاد شده، انتظار دارد که id فیلم مورد نظر را از طریق URL دریافت کند (مثلاً /Movies/Details/1). این کار با افزودن دایرکتیو @page "{id:int}" در ابتدای فایل .cshtml انجام می‌شود.

سپس، در متد هندلر OnGetAsync، می‌توانیم یک پارامتر با همان نام (`id`) تعریف کنیم. سیستم Model Binding به طور خودکار مقدار را از URL استخراج کرده و به این پارامتر اختصاص می‌دهد.

Copy Icon Details.cshtml.cs
// The 'id' parameter is bound from the route value.
public async Task<IActionResult> OnGetAsync(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    Movie = await _context.Movie.FirstOrDefaultAsync(m => m.Id == id);

    if (Movie == null)
    {
        return NotFound();
    }
    return Page();
}

در اینجا، اگر کاربر به آدرس /Movies/Details/5 مراجعه کند، سیستم Model Binding مقدار 5 را به پارامتر id متد OnGetAsync اختصاص می‌دهد.

دریافت داده از فرم‌های HTML

برای عملیاتی که داده‌ها را تغییر می‌دهند (مانند ایجاد یا ویرایش)، ما معمولاً از فرم‌های HTML و درخواست‌های HTTP POST استفاده می‌کنیم. در این حالت، داده‌ها در بدنه‌ی درخواست HTTP ارسال می‌شوند.

سیستم Model Binding در ASP.NET Core می‌تواند این داده‌های فرم را به پراپرتی‌های کلاس PageModel ما متصل کند. کلید اصلی برای این کار، صفت [BindProperty] است.

مثال: صفحه‌ی Create

بیایید دوباره به کد تولید شده برای Create.cshtml.cs نگاه کنیم:

Copy Icon Create.cshtml.cs
[BindProperty]
public Movie Movie { get; set; }

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    _context.Movie.Add(Movie);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

در اینجا، صفت [BindProperty] به ASP.NET Core می‌گوید که پراپرتی Movie باید از روی داده‌های درخواست ورودی مقداردهی شود. در فایل Create.cshtml، فیلدهای فرم با استفاده از تگ هلپرهای ASP.NET Core (مانند asp-for) به پراپرتی‌های شیء Movie متصل شده‌اند:

Copy Icon Create.cshtml (Partial)
<form method="post">
    <div class="form-group">
        <label asp-for="Movie.Title"></label>
        <input asp-for="Movie.Title" class="form-control" />
    </div>
    <!-- Other form fields... -->
    <input type="submit" value="Create" />
</form>

وقتی کاربر فرم را ارسال می‌کند، Model Binder مقادیر فیلدهای فرم را می‌خواند (مثلاً مقدار فیلد Movie.Title) و یک نمونه‌ی جدید از کلاس Movie را با این مقادیر ایجاد کرده و آن را به پراپرتی Movie در PageModel اختصاص می‌دهد. سپس هندلر OnPostAsync با این شیء Movie که به طور کامل پر شده است، کار خود را انجام می‌دهد. این مکانیزم، فرآیند کار با داده‌های فرم را بسیار ساده و امن می‌کند.