شروع کار با صفحات Razor در ASP.NET Core 2.0

امروز بیشتر درباره ی صفحات Razor ، اینکه صفحات Razor چه هستند؟ چگونگی ساخت آن ها و برخی ویژگی های پایه ای صفحات Razor مانند امنیت ، Template ، Page@ ، به روزرسانی خودکار Model و غیره صحبت خواهیم کرد.

 شروع کار با صفحات Razor در ASP.NET Core 2.0

ASP.NET Core 2.0 چند ویژگی جدید معرفی کرده است که یک template پروژه ی جدید یکی از این ویژگی هاست. مایکروسافت چند template جدید پروژه ی معرفی کرده است که در ساخت انواع اپلیکیشن ها به جز MVC و Web API کمک می کند. حال ما می توانیم اپلیکیشن های Razor Page و اپلیکیشن های SPA را با استفاده از Angular  یا React بسازیم. امروز بیشتر درباره ی صفحات Razor -اینکه صفحات Razor چه هستند؟ چگونگی ساخت آن ها و برخی ویژگی های پایه ای صفحات Razor صحبت خواهیم کرد.

صفحات Razor بیشتر شبیه MVC هستند و بسیاری از ویژگی های MVC را دارد اما MVC روی controller تمرکز می کند ولی Razor Page روی پیاده سازی UI تمرکز می کند.

چرا Razor Page

اولین سوالی که زمان مطالعه درباره ی Razor Page به ذهن می رسد این است که چرا از Razor Page به جای MVC استفاده کنیم؟ جواب این سوال یک خط است و می توانیم بگوییم که زمانی که روی UI تمرکز می کنیم یا وقتی به UI نسبت به ساختار های پیچیده یا منطق داده ها اولویت می دهیم می توانیم از Razor Page به جای MVC استفاده کنیم.

درواقع در یک پروژه ی MVC که Controller, View, Model, View-Model, Routing و غیره با یکدیگر یک گروه تشکیل داده اند تا اپلیکیشن اجرا شود، اگر شما یک عملکرد واحد را تغییر دهید یا اضافه کنید (مانند اینکه می خواهید یک ویژگی جدید اضافه کنید) باید در ViewModel در قسمت Entity های مربوطه، نگاشت داده های آن و همچنین View تغییراتی ایجاد کنید.

اما Razor Page فقط برای اپلیکیشن های کوچکی است که می خواهید بطور عمده روی View تمرکز کنید. اگر شما تغییری ایجاد کنید باید Razor Page خود [.cshtml] را نیز تغییر دهید. کد های سمت سرور نیز می تواند در Razor Page با استفاده از دایرکتیو function@ نوشته شود. اگر می خواهید که یک فایل جدا برای کد های منطقی خود ایجاد کنید می توانید فایل code-behind که از PageModel ارث بری می کند را بسازید.

ساخت اپلیکیشن Razor Page

برای ساخت یک اپلیکیشن Razor Page باید Visual Studio 2017 نسخه ی 15.3 یا بالاتر را با NET Core SDK 2.0. روی سیستم خود نصب داشته باشید. شما می توانید NET Core SDK 2.0. را از اینجا دانلود کنید و Visual Studio خود را با استفاده از “Visual Studio Installer” به روزرسانی کنید.

برای ساخت یک اپلیکیشن جدید Razor Page مثل همیشه که یک پروژه ی جدید می سازید به  File >> New >>Project بروید.

از پنجره ی  "New Project" ، NET Core. را از پنل سمت چپ انتخاب کنید و از پنل مرکزی نیز “ASP.NET Core Web Application” را انتخاب کنید سپس نام و مکان را برای ذخیره سازی مشخص کنید و سپس روی OK کلیک کنید.

از پنجره ی بعدی باید template که مسئول ساخت یک Razor page است را انتخاب کنید. “Web Application” را همانطور که در تصویر زیر نشان داده شده است انتخاب کنید. Authentication را به “No Authentication” تغییر دهید و روی OK کلیک کنید.

پس از کلیک کردن روی OK پیکربندی اپلیکیشن Razor Page شما چند ثانیه طول می کشد و سرانجام اپلیکیشن شما مانند تصویر زیر ساخته خواهد شد.

تصویر بالا ساختار کلی Razor Page است که بسیار شبیه اپلیکیشن MVC می باشد اما شما اینجا هیچ پوشه ی Controller و Model نمی بینید اما یک پوشه ی مهم به نام “Pages” وجود دارد که شامل همه ی صفحات Razor و فایل های code-behind مرتبط، می باشد. فایل های code-behind یا Model Page ها اساسا برای جداسازی وظایف استفاده می شوند بقیه موارد نظیر Program.cs و Startup.cs عمدتا شبیه MVC می باشد.

حال شما می توانید اپلیکیشن را اجرا کنید و خروجی را همانطور که در تصویر زیر نشان داده شده ببینید.

برای اضافه کردن یک صفحه ی Razor جدید روی پوشه ی Pages یا هر پوشه ی دیگر در Pages راست کلیک کنید و Add > Razor Page را برای اضافه کردن دایرکتوری انتخاب کنید.

یک پنجره ی جدید باز خواهد شد که شما می توانید نوع واقعی Razor page های خود را انتخاب کنید شما ممکن است در حال استفاده از Razor با Entity Framework باشید یا بخواهید کد های CRUD را به صورت خودکار با استفاده از ویژگی Scaffold بنویسید.

Template

Template معمول Razor در مواردی مانند “_viewStart.cshtml”, “_layout.cshtml”, “about.cshtml” و غیره شبیه MVC می باشد اما در اینجا فقط ساختار پوشه با Razor Page ها تغییر کرده است. در MVC این موارد، پوشه های از پیش تعریف شده ی خود را دارند برای یک template معمول ما از پوشه ی “Shared” در پوشه ی View استفاده می کنیم . هر عملیات، پوشه ی View مرتبط با خود را دارد مانند Home, Employee و غیره.

Page@

هر صفحه ی Razor یک دایرکتیو Page@ دارد که مشخص می کند که MVC Razor View معمولی نیست بلکه یک Razor Page می باشد.

@page    
@model AboutModel    
@{    
    ViewData["Title"] = "About";    
}    
<h2>@ViewData["Title"]</h2>    
<h3>@Model.Message</h3>    
<p>Use this area to provide additional information.</p> 

Code Behind یا Model Page

برای نوشتن منطق سمت سرور می توانیم یک فایل cshtml.cs برای code-behind همانطور که کد زیر نشان داده شده بسازیم که شامل همه ی منطق های سمت سرور نظیر گرفتن داده از سرور، ارسال داده روی سرور می باشد. اینجا می توانیم از OnGet و OnPost برای دریافت و ارسال داده ها استفاده کنیم.

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Threading.Tasks;  
using Microsoft.AspNetCore.Mvc.RazorPages;  
  
namespace RazorPagesExample.Pages  
{  
    public class AboutModel : PageModel  
    {  
        public string Message { get; set; }  
  
        public void OnGet()  
        {  
            Message = "Your application description page.";  
        }  
    }  
}  

Razor Page بدون فایل Code Behind

Model Binding

ما می توانیم مستقیما ویژگی ها را با Razor Page با استفاده از ویژگی [BindProperty] الحاق کنیم. ویژگی ایجاد شده با خاصیت [BindProperty] می تواند بطور خودکار در صفحه ی Razor دردسترس باشد.

using System;  
using System.Collections.Generic;  
using System.ComponentModel.DataAnnotations;  
using System.Linq;  
using System.Threading.Tasks;  
using Microsoft.AspNetCore.Mvc;  
using Microsoft.AspNetCore.Mvc.RazorPages;  
  
namespace RazorPagesExample.Pages.Employee  
{  
    public class IndexModel : PageModel  
    {  
        [BindProperty]  
        public Employee employee { get; set; }  
        public void OnGet()  
        {  
  
        }  
  
        public void OnPost()  
        {  
            var data = employee;  
        }  
    }  
  
    public class Employee  
    {  
        public int ID { get; set; }  
  
        [Required]  
        [StringLength(50, ErrorMessage = "Name lenght should be 1 to 50.")]  
        [Display(Name = "Employee Name")]  
        public string Name { get; set; }  
  
        [Required]  
        [StringLength(255, ErrorMessage = "Address lenght should be 1 to 255.")]  
        [Display(Name = "Address")]  
        public string Address { get; set; }  
    }  
}  

در صفحه ی Razor فقط از نام ویژگی ها استفاده کنید و کنترل ورودی ها را با آن الحاق کنید.

@page  
@model RazorPagesExample.Pages.Employee.IndexModel  
@{  
    ViewData["Title"] = "Employee Page";  
}  
  
<h2>@ViewData["Title"]</h2>  
<div class="row">  
    <div class="col-md-6">  
        <form method="post">  
            <div class="form-group">  
                <label asp-for="employee.Name"></label>  
                <input asp-for="employee.Name" class="form-control" />  
                <span asp-validation-for="employee.Name" class="text-danger"></span>  
            </div>  
            <div class="form-group">  
                <label asp-for="employee.Address"></label>  
                <input asp-for="employee.Address" class="form-control" />  
                <span asp-validation-for="employee.Address" class="text-danger"></span>  
            </div>  
            <button type="submit" class="btn btn-default">Add Employee</button>  
        </form>  
    </div>  
</div>  

(Model Auto-Updating) به روز رسانی خودکار Model

مدل تعریف شده با صفحه ی Razor به صورت خودکار در فایل Code-Behind به روزرسانی خواهد شد. شما نیاز ندارید که برای الحاق (bind) مدل خود با عملیات مشخصی نگران باشید. هر تغییری در داده های مدل در مدل مربوط به خود بازتاب داده خواهد شد.

با کد بالا می توانید ببینید که اگر روی دکمه ی “Add Employee” کلیک کنید و داده های درست برای جلوگیری از ارور بفرستید داده ها با مدل الحاق می شوند و در OnPost handler همانطور که در ادامه آمده است بازتاب داده می شود. در اینجا ما همانند MVC مدل را به عنوان یک پارامتر ارسال نمی کنیم.

Tag Helper ها

همانطور که همه ی ما می دانیم تگ helper اساسا یکی از ویژگی های Asp.Net MVC می باشد که در Razor Page هم وجود دارد. حال شما می توانید مستقیما داده های خود را با Razor Page و با استفاده از تگ Helper الحاق کنید. همانطور که کد زیر نشان می دهد از تگ Helper های زیادی مانند “asp-for”, “asp-validation-for” و غیره استفاده می کنیم.

<form method="post">  
            <div class="form-group">  
                <label asp-for="employee.Name"></label>  
                <input asp-for="employee.Name" class="form-control" />  
                <span asp-validation-for="employee.Name" class="text-danger"></span>  
            </div>  
            <div class="form-group">  
                <label asp-for="employee.Address"></label>  
                <input asp-for="employee.Address" class="form-control" />  
                <span asp-validation-for="employee.Address" class="text-danger"></span>  
            </div>  
            <button type="submit" class="btn btn-default">Add Employee</button>  
        </form>  

Handler ها

ما از handler ها برای انجام عملیات های سمت سرور نظیر گرفتن داده و ارسال داده استفاده می کنیم. این handler ها چیزی شبیه عبارات Http استفاده شده در MVC نظیر() Get(), Post و غیره می باشد.

به عنوان یک پیشوند ما از “On” با عبارات Http در Razor Page استفاده می کنیم که نشان دهنده ی این است یک event یا handler به عنوان OnGet() ، OnGetAsync(), OnPost() ، OnPostAsync() یا غیره می باشد.

مسیردهی

در مقایسه با مسیردهی MVC ، مسیردهی Razor Page بسیار آسان است. ما نیاز نداریم که برای مسیردهی های ساده کد را دستی بنویسیم. تمام صفحات در پوشه ی Pages با نام فایل بعد از نام domain فراخوانی می شوند.

http://localhost:51068/index

http://localhost:51068/about

http://localhost:51068/employee/index 

اگر شما می خواهید با URL پارامتر ارسال کنید می توانید پارامتر ها را با دایرکتیو page@ مانند کد زیر اضافه کنید. در اینجا می توانید ببینید که در حال ارسال یک id از نوع integer هستیم.

@page "{id:int}"  
@model RazorPagesExample.Pages.Employee.IndexModel  
@{  
    ViewData["Title"] = "Employee Page";  
}

بنابراین وقتی شما URL را فراخوانی می کنید باید ID که از نوع integer می باشد را مانند URL زیر ارسال کنید.

http://localhost:51068/employee/index/1

امنیت

زمانی که ما از امنیت با Razor Page ها نظیر حملات CSRF صحبت می کنیم مانند MVC نیاز به کدهای دستی برای حفظ اپلیکیشن از دنیای خارجی نداریم و نیاز به اضافه کردن AntiRequestForgery Token یا تغییر آن نداریم. این وظایف در داخل خود Razor Page به صورت خودکار انجام می شود.