مقدمه
در درسهای گذشته، با استفاده از ابزارهای 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 استخراج کرده و به این پارامتر اختصاص میدهد.
Details.cshtml.cs
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 نگاه کنیم:
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 متصل شدهاند:
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>
<input type="submit" value="Create" />
</form>
وقتی کاربر فرم را ارسال میکند، Model Binder مقادیر فیلدهای فرم را میخواند (مثلاً مقدار فیلد
Movie.Title) و یک نمونهی جدید از کلاس Movie را با این مقادیر ایجاد کرده و آن را به پراپرتی
Movie در PageModel اختصاص میدهد. سپس هندلر OnPostAsync با این شیء Movie که به طور کامل
پر شده است، کار خود را انجام میدهد. این مکانیزم، فرآیند کار با دادههای فرم را بسیار ساده و امن
میکند.