ASP.NET Core'da Razor Pages'a Giriş
Rick Anderson, Dave Brock ve Kirk Larkin
Uyarı
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.
Razor Pages, kod sayfası odaklı senaryoların denetleyici ve görünümleri kullanmaya kıyasla daha kolay ve daha üretken olmasını sağlayabilir.
Model-Görünüm-Denetleyici yaklaşımını kullanan bir öğretici arıyorsanız bkz. ASP.NET Core MVC'yi kullanmaya başlama.
Bu belgede Razor Pages'a giriş bilgileri sağlanır. Bu adım adım bir öğretici değildir. Bölümlerden bazılarının fazla ileri düzeyde olduğunu düşünüyorsanız, bkz. Razor Pages'ı kullanmaya başlama. ASP.NET Core'a genel bir bakış için bkz. ASP.NET Core'a giriş.
Önkoşullar
- Visual Studio 2022 ile ASP.NET ve web geliştirme iş yükü.
- .NET 6.0 SDK
Razor Pages projesi oluşturma
Razor Pages projesi oluşturmaya yönelik ayrıntılı yönergeler için bkz. Razor Pages'ı kullanmaya başlama.
Razor Pages
Razor Pages Program.cs
dosyasında etkinleştirilir:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Önceki kodda:
- AddRazorPages uygulamaya Razor Pages için hizmetler ekler.
- MapRazorPages IEndpointRouteBuilder arabirimine Razor Pages için uç noktalar ekler.
@page
<h1>Hello, world!</h1>
<h2>The time on the server is @DateTime.Now</h2>
Yukarıdaki kod, ASP.NET Core uygulamasında denetleyiciler ve görünümlerle kullanılan bir Razor görünüm dosyasına çok benzer. Bunu farklı kılan @page
yönergesidir. @page
dosyayı bir MVC eylemine dönüştürür. Bu da istekleri bir denetleyiciden geçmeden, doğrudan işlediği anlamına gelir. @page
, sayfadaki ilk Razor yönergesi olmalıdır. @page
diğer Razor yapılarının davranışını etkiler. Razor Pages dosya adlarının .cshtml
soneki vardır.
Aşağıdaki iki dosyada PageModel
sınıfının kullanıldığı benzer bir sayfa gösterilir. Pages/Index2.cshtml
dosyası:
@page
@using RazorPagesIntro.Pages
@model Index2Model
<h2>Separate page model</h2>
<p>
@Model.Message
</p>
Pages/Index2.cshtml.cs
sayfa modeli:
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System;
namespace RazorPagesIntro.Pages
{
public class Index2Model : PageModel
{
public string Message { get; private set; } = "PageModel in C#";
public void OnGet()
{
Message += $" Server time is { DateTime.Now }";
}
}
}
Kural gereği PageModel
sınıf dosyasının adı sonuna .cs
eklenmiş Razor Sayfa dosyasının adıyla aynıdır. Örneğin yukarıdaki Razor Sayfası Pages/Index2.cshtml
adını taşır. PageModel
sınıfını içeren dosya Pages/Index2.cshtml.cs
olarak adlandırılır.
URL yollarının sayfalarla ilişkileri, sayfanın dosya sistemindeki konumuna göre belirlenir. Aşağıdaki tabloda bir Razor Sayfa yolu ve eşleşen URL gösterilir:
Dosya adı ve yol | eşleşen URL |
---|---|
/Pages/Index.cshtml |
/ veya /Index |
/Pages/Contact.cshtml |
/Contact |
/Pages/Store/Contact.cshtml |
/Store/Contact |
/Pages/Store/Index.cshtml |
/Store veya /Store/Index |
Notlar:
- Çalışma zamanı Razor Pages dosyalarını varsayılan olarak Pages klasöründe arar.
- URL bir sayfa içermediğinde varsayılan sayfa
Index
sayfasıdır.
Temel form yazma
Razor Pages, web tarayıcıları tarafından kullanılan yaygın desenlerin uygulama oluşturulurken kolayca uygulanmasını sağlamak için tasarlanmıştır. Model bağlama, Etiket Yardımcıları ve HTML yardımcıları, Razor Sayfa sınıfında tanımlanan özelliklerle çalışır. Contact
modeli için temel bir "bize ulaşın" formu uygulayan bir sayfayı düşünün:
Bu belgedeki örnekler için , DbContext
Program.cs dosyasında başlatılır.
Bellek içi veritabanı Microsoft.EntityFrameworkCore.InMemory
NuGet paketini gerektirir.
using Microsoft.EntityFrameworkCore;
using RazorPagesContacts.Data;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddDbContext<CustomerDbContext>(options =>
options.UseInMemoryDatabase("name"));
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Veri modeli:
using System.ComponentModel.DataAnnotations;
namespace RazorPagesContacts.Models
{
public class Customer
{
public int Id { get; set; }
[Required, StringLength(10)]
public string? Name { get; set; }
}
}
Veritabanı bağlamı:
using Microsoft.EntityFrameworkCore;
namespace RazorPagesContacts.Data
{
public class CustomerDbContext : DbContext
{
public CustomerDbContext (DbContextOptions<CustomerDbContext> options)
: base(options)
{
}
public DbSet<RazorPagesContacts.Models.Customer> Customer => Set<RazorPagesContacts.Models.Customer>();
}
}
Pages/Customers/Create.cshtml
görünüm dosyası:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Enter a customer name:</p>
<form method="post">
Name:
<input asp-for="Customer!.Name" />
<input type="submit" />
</form>
Pages/Customers/Create.cshtml.cs
sayfa modeli:
public class CreateModel : PageModel
{
private readonly Data.CustomerDbContext _context;
public CreateModel(Data.CustomerDbContext context)
{
_context = context;
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public Customer? Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
if (Customer != null) _context.Customer.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
Kurala göre PageModel
sınıfı <PageName>Model
olarak adlandırılır ve sayfayla aynı ad alanında yer alır.
PageModel
sınıfı, bir sayfanın mantığının sunumundan ayrılmasına olanak sağlar. Sayfaya gönderilen istekler için herhangi bir sayfa işleyicisini ve sayfayı işlemek için kullanılan verileri tanımlar. Bu ayrım şunları sağlar:
- Bağımlılık ekleme aracılığıyla sayfa bağımlılıklarını yönetme.
- Birim testi
Sayfada istekler üzerinde POST
(kullanıcı formu gönderdiğinde) çalışan bir OnPostAsync
işleyici yöntemi vardır. Herhangi bir HTTP fiili için işleyici yöntemleri eklenebilir. En yaygın işleyiciler şunlardır:
- Sayfa için gereken durumu başlatmak için
OnGet
. Yukarıdaki koddaOnGet
yöntemiCreate.cshtml
Razor Sayfasını görüntüler. - Form gönderilerini işlemek için
OnPost
.
Async
adlandırma son eki isteğe bağlıdır, ancak genellikle zaman uyumsuz işlevler için kural tarafından kullanılır. Yukarıdaki kod, Razor Pages için tipik bir koddur.
Denetleyicileri ve görünümleri kullanan ASP.NET uygulamalarını biliyorsanız:
- Yukarıdaki örnekte yer alan
OnPostAsync
kodu tipik bir denetleyici koduna benzer. - Model bağlama, doğrulama ve eylem sonuçları gibi MVC temel öğelerinin çoğu, Denetleyiciler ve Razor Pages ile aynı şekilde çalışır.
Yukarıdaki OnPostAsync
yöntemi:
[BindProperty]
public Customer? Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
if (Customer != null) _context.Customer.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
OnPostAsync
temel akışı:
Doğrulama hatalarını denetleyin.
- Hata yoksa, verileri kaydedin ve yeniden yönlendirin.
- Hatalar varsa, doğrulama iletileriyle birlikte sayfayı yeniden gösterin. Çoğu durumda, doğrulama hataları istemci üzerinde algılanır ve sunucuya hiçbir zaman gönderilmez.
Pages/Customers/Create.cshtml
görünüm dosyası:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Enter a customer name:</p>
<form method="post">
Name:
<input asp-for="Customer!.Name" />
<input type="submit" />
</form>
Pages/Customers/Create.cshtml
dosyasından işlenen HTML:
<p>Enter a customer name:</p>
<form method="post">
Name:
<input type="text" data-val="true"
data-val-length="The field Name must be a string with a maximum length of 10."
data-val-length-max="10" data-val-required="The Name field is required."
id="Customer_Name" maxlength="10" name="Customer.Name" value="" />
<input type="submit" />
<input name="__RequestVerificationToken" type="hidden"
value="<Antiforgery token here>" />
</form>
Yukarıdaki kodda formu gönderme:
Geçerli verilerle:
OnPostAsync
işleyici yöntemi RedirectToPage yardımcı yöntemini çağırır.RedirectToPage
, bir RedirectToPageResult örneği döndürür.RedirectToPage
:- Bir eylemin sonucudur.
RedirectToAction
veyaRedirectToRoute
yöntemine benzer (denetleyicilerde ve görünümlerde kullanılır).- Sayfalar için özelleştirilir. Yukarıdaki örnekte kök Dizin sayfasına yeniden yönlendirir (
/Index
).RedirectToPage
, Sayfalar için URL oluşturma bölümünde ayrıntılı olarak açıklanır.
Sunucuya geçirilen doğrulama hatalarıyla:
OnPostAsync
işleyici yöntemi Page yardımcı yöntemini çağırır.Page
, bir PageResult örneği döndürür. DöndürülenPage
, denetleyicilerdeki eylemlerinView
döndürmesine benzer.PageResult
, işleyici yöntemi için varsayılan dönüş türüdür.void
döndüren bir işleyici yöntemi sayfayı işler.- Yukarıdaki örnekte formu hiç değer olmadan göndermek ModelState.IsValid özelliğinin false döndürmesiyle sonuçlanır. Bu örnekte istemcide doğrulama hatası görüntülenmez. Doğrulama hatasının işlenmesi, bu belgenin ilerleyen bölümlerinde ele alınmıştır.
[BindProperty] public Customer? Customer { get; set; } public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } if (Customer != null) _context.Customer.Add(Customer); await _context.SaveChangesAsync(); return RedirectToPage("./Index"); }
İstemci tarafı doğrulaması tarafından algılanan doğrulama hatalarıyla:
- Veriler sunucuya gönderilmez.
- İstemci tarafı doğrulaması, bu belgenin ilerleyen bölümlerinde açıklanmıştır.
Customer
özelliği model bağlamayı kabul etmek için [BindProperty]
özniteliğini kullanır:
[BindProperty]
public Customer? Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
if (Customer != null) _context.Customer.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
[BindProperty]
, istemi tarafından değiştirilmemesi gereken özelliklerin bulunduğu modellerde kullanılmamalıdır. Daha fazla bilgi için bkz. Aşırı gönderim.
Razor Pages varsayılan olarak özellikleri yalnızca GET
dışındaki fiillerle bağlar. Özelliklere bağlama işlemi HTTP verilerini model türüne dönüştürmek üzere kod yazma gereğini ortadan kaldırır. Bağlama, form alanlarını işlemek ve girişi kabul etmek için aynı özelliği kullanarak (<input asp-for="Customer.Name">
) kodu azaltır.
Uyarı
Güvenlik nedeniyle GET
isteği verilerini sayfa modeli özelliklerine bağlamayı kabul etmeniz gerekir. Kullanıcı girişini özelliklere eşlemeden önce doğrulayın. Sorgu dizesi veya yönlendirme değerlerini kullanan senaryolarla ilgilenirken GET
bağlamasını kabul etmek yararlı olur.
GET
isteklerinde bir özelliği bağlamak için [BindProperty]
özniteliğinin SupportsGet
özelliğini true
olarak ayarlayın:
[BindProperty(SupportsGet = true)]
Daha fazla bilgi için bkz. ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Pages/Customers/Create.cshtml
görünüm dosyasını gözden geçirme:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Enter a customer name:</p>
<form method="post">
Name:
<input asp-for="Customer!.Name" />
<input type="submit" />
</form>
- Önceki kodda , giriş etiketi yardımcısı
<input asp-for="Customer.Name" />
HTML<input>
öğesini model ifadesineCustomer.Name
bağlar. @addTagHelper
, Etiket Yardımcılarını kullanılabilir duruma getirir.
Sayfa home
Index.cshtml
home sayfa:
@page
@model RazorPagesContacts.Pages.Customers.IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<h1>Contacts home page</h1>
<form method="post">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th></th>
</tr>
</thead>
<tbody>
@if (Model.Customers != null)
{
foreach (var contact in Model.Customers)
{
<tr>
<td> @contact.Id </td>
<td>@contact.Name</td>
<td>
<!-- <snippet_Edit> -->
<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |
<!-- </snippet_Edit> -->
<!-- <snippet_Delete> -->
<button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button>
<!-- </snippet_Delete> -->
</td>
</tr>
}
}
</tbody>
</table>
<a asp-page="Create">Create New</a>
</form>
İlişkili PageModel
sınıfı (Index.cshtml.cs
):
public class IndexModel : PageModel
{
private readonly Data.CustomerDbContext _context;
public IndexModel(Data.CustomerDbContext context)
{
_context = context;
}
public IList<Customer>? Customers { get; set; }
public async Task OnGetAsync()
{
Customers = await _context.Customer.ToListAsync();
}
public async Task<IActionResult> OnPostDeleteAsync(int id)
{
var contact = await _context.Customer.FindAsync(id);
if (contact != null)
{
_context.Customer.Remove(contact);
await _context.SaveChangesAsync();
}
return RedirectToPage();
}
}
Index.cshtml
dosyası aşağıdaki işaretlemeyi içerir:
<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |
Tutturucu <a /a>
Etiketi Yardımcısı , Düzenle sayfasına bağlantı oluşturmak için özniteliğini kullandı asp-route-{value}
. Bağlantı, kişi kimliğiyle birlikte yönlendirme verilerini içerir. Örneğin, https://localhost:5001/Edit/1
. Etiket Yardımcıları, Razor dosyalarında HTML öğelerinin oluşturulmasına ve işlenmesine sunucu tarafı kodun katılmasını etkinleştirir.
Index.cshtml
dosyası her müşteri kişisi için bir sil düğmesi oluşturmaya yönelik işaretleme içerir:
<button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button>
İşlenen HTML:
<button type="submit" formaction="/Customers?id=1&handler=delete">delete</button>
Sil düğmesi HTML'de işlendiğinde formaction öğesi şu parametreleri içerir:
asp-route-id
özniteliğiyle belirtilen müşteri kişi kimliği.asp-page-handler
özniteliğiyle belirtilenhandler
.
Düğme seçildiğinde sunucuya bir form POST
isteği gönderilir. Kurala göre işleyici yönteminin adı, OnPost[handler]Async
şemasına uygun olarak handler
parametresinin değeri temelinde seçilir.
Bu örnekte handler
delete
olduğundan, POST
isteğini işlemek için OnPostDeleteAsync
işleyici yöntemi kullanılır. asp-page-handler
farklı bir değere ayarlanırsa (örneğin remove
), OnPostRemoveAsync
adlı bir işleyici yöntemi seçilir.
public async Task<IActionResult> OnPostDeleteAsync(int id)
{
var contact = await _context.Customer.FindAsync(id);
if (contact != null)
{
_context.Customer.Remove(contact);
await _context.SaveChangesAsync();
}
return RedirectToPage();
}
OnPostDeleteAsync
yöntemi:
- Sorgu dizesinden
id
değerini alır. FindAsync
ile müşteri kişisi için veritabanını sorgular.- Müşteri kişisi bulunursa kaldırılır ve veritabanı güncelleştirilir.
- Kök Dizin sayfasını (
/Index
) yeniden yönlendirmek için RedirectToPage yöntemini çağırır.
Edit.cshtml dosyası
@page "{id:int}"
@model RazorPagesContacts.Pages.Customers.EditModel
@{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>Customer</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Customer!.Id" />
<div class="form-group">
<label asp-for="Customer!.Name" class="control-label"></label>
<input asp-for="Customer!.Name" class="form-control" />
<span asp-validation-for="Customer!.Name" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="./Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
İlk satır @page "{id:int}"
yönergesini içerir. "{id:int}"
yönlendirme kısıtlaması sayfaya int
yönlendirme verilerini içeren istekleri kabul etmesini bildirir. Sayfaya yönelik istek int
öğesine dönüştürülebilecek yönlendirme verilerini içermiyorsa, çalışma zamanı bir HTTP 404 (bulunamadı) hatası döndürür. Kimliği isteğe bağlı yapmak için yönlendirme kısıtlamasının sonuna ?
ekleyin:
@page "{id:int?}"
Edit.cshtml.cs
dosyası:
public class EditModel : PageModel
{
private readonly RazorPagesContacts.Data.CustomerDbContext _context;
public EditModel(RazorPagesContacts.Data.CustomerDbContext context)
{
_context = context;
}
[BindProperty]
public Customer? Customer { get; set; }
public async Task<IActionResult> OnGetAsync(int? id)
{
if (id == null)
{
return NotFound();
}
Customer = await _context.Customer.FirstOrDefaultAsync(m => m.Id == id);
if (Customer == null)
{
return NotFound();
}
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
if (Customer != null)
{
_context.Attach(Customer).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!CustomerExists(Customer.Id))
{
return NotFound();
}
else
{
throw;
}
}
}
return RedirectToPage("./Index");
}
private bool CustomerExists(int id)
{
return _context.Customer.Any(e => e.Id == id);
}
}
Doğrulama
Doğrulama kuralları:
- Model sınıfında bildirim temelli olarak belirtilir.
- Uygulamanın her yerinde zorlanır.
System.ComponentModel.DataAnnotations ad alanı, bir sınıfa veya özelliğe uygulanan bir dizi yerleşik doğrulama özniteliği sağlar. DataAnnotations biçimlendirmeye yardımcı olan ve hiçbir doğrulama sağlamayan [DataType]
gibi biçimlendirme öznitelikleri de içerir.
Customer
modelini ele alalım:
using System.ComponentModel.DataAnnotations;
namespace RazorPagesContacts.Models
{
public class Customer
{
public int Id { get; set; }
[Required, StringLength(10)]
public string? Name { get; set; }
}
}
Aşağıdaki Create.cshtml
görünüm dosyasını kullanarak:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Validation: customer name:</p>
<form method="post">
<div asp-validation-summary="ModelOnly"></div>
<span asp-validation-for="Customer!.Name"></span>
Name:
<input asp-for="Customer!.Name" />
<input type="submit" />
</form>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
Yukarıdaki kod:
jQuery ve jQuery doğrulama betiklerini içerir.
<div />
Etkinleştirmek için ve<span />
Etiket Yardımcılarını kullanır:- İstemci tarafı doğrulaması.
- Doğrulama hatası işleme.
Aşağıdaki HTML'yi oluşturur:
<p>Enter a customer name:</p> <form method="post"> Name: <input type="text" data-val="true" data-val-length="The field Name must be a string with a maximum length of 10." data-val-length-max="10" data-val-required="The Name field is required." id="Customer_Name" maxlength="10" name="Customer.Name" value="" /> <input type="submit" /> <input name="__RequestVerificationToken" type="hidden" value="<Antiforgery token here>" /> </form> <script src="/lib/jquery/dist/jquery.js"></script> <script src="/lib/jquery-validation/dist/jquery.validate.js"></script> <script src="/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
Ad değeri olmadan Create form gönderilmesi, formda "Ad alanı zorunludur." hata iletisinin görüntülenmesine neden olur. İstemcide JavaScript etkinleştirildiyse tarayıcı hatayı sunucuya göndermeden görüntüler.
[StringLength(10)]
özniteliği işlenen HTML'de data-val-length-max="10"
oluşturur. data-val-length-max
, tarayıcıların belirtilen maksimum uzunluktan fazlasını girmesini önler. Gönderiyi düzenlemek ve yeniden yürütmek için Fiddler gibi bir araç kullanılırsa:
- 10 karakterden uzun bir ad ile.
- "Alan Adı uzunluk üst sınırı 10 olan bir dize olmalıdır." hata iletisi döndürülür.
Aşağıdaki Movie
modeli ele alalım:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RazorPagesMovie.Models
{
public class Movie
{
public int ID { get; set; }
[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
[Required]
[StringLength(30)]
public string Genre { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
[StringLength(5)]
[Required]
public string Rating { get; set; }
}
}
Doğrulama öznitelikleri, uygulandıkları model özelliklerinde zorlanacak davranışı belirtir:
Required
veMinimumLength
öznitelikleri özelliğin bir değer olması gerektiğini belirtir ama kullanıcının bu doğrulamaya uymak için boşluk girmesi engellenemez.RegularExpression
özniteliği girilebilecek karakterleri sınırlamak için kullanılır. Yukarıdaki kodda "Genre":- Yalnızca harfleri kullanmalıdır.
- İlk harfin büyük harf olması gerekir. Boşluk, sayı ve özel karakterlere izin verilmez.
RegularExpression
"Rating":- İlk karakterin büyük harf olmasını gerektirir.
- Sonraki alanlarda özel karakterlere ve sayılara izin verir. "PG-13" değeri Rating için geçerlidir ama "Genre" için başarısız olur.
Range
özniteliği, bir değeri belirtilen bir aralık içinde kısıtlar.StringLength
özniteliği bir dize özelliğinin boyut üst sınırını ve isteğe bağlı olarak boyut alt sınırını ayarlar.Değer türleri (
decimal
,int
,float
,DateTime
gibi) doğal olarak gereklidir ve[Required]
özniteliği gerekmez.
Movie
modeli için Create page, geçersiz değerleri içeren hatalar görüntüler:
Daha fazla bilgi için bkz.
CSS yalıtımı
Aşağıdakileri azaltmak veya önlemek için CSS stillerini tek tek sayfalara, görünümlere ve bileşenlere yalıtır:
- Bakımı zor olabilen genel stillere bağımlılıklar.
- İç içe yerleştirilmiş içerikte stil çakışmaları.
Bir sayfa veya görünüme kapsamlı CSS dosyası eklemek için CSS stillerini .cshtml
dosyasının adıyla eşleşen bir yardımcı .cshtml.css
dosyasına yerleştirir. Aşağıdaki örnekte, yalnızca Index.cshtml
sayfası ya da görünümüne CSS stillerini sağlayan bir Index.cshtml.css
dosyası bulunuyor.
Pages/Index.cshtml.css
(Razor Pages) veya Views/Index.cshtml.css
(MVC):
h1 {
color: red;
}
CSS yalıtımı derleme zamanında gerçekleşir. Çerçeve, uygulamanın sayfaları veya görünümleri tarafından işlenen işaretlemeyle eşleşecek şekilde CSS seçicileri yeniden yazar. Yeniden yazılan CSS stilleri statik bir varlık ({APP ASSEMBLY}.styles.css
) olarak paketlenir ve oluşturulur. {APP ASSEMBLY}
yer tutucusu projenin derleme adıdır. Paketlenmiş CSS stillerinin bağlantısı uygulamanın düzenine yerleştirilir.
Uygulamanın Pages/Shared/_Layout.cshtml
(Razor Pages) veya Views/Shared/_Layout.cshtml
(MVC) dosyasının <head>
içeriğinde, paketlenmiş CSS stillerinin bağlantısını ekleyin veya bağlantının mevcut olduğunu onaylayın:
<link rel="stylesheet" href="~/{APP ASSEMBLY}.styles.css" />
Aşağıdaki örnekte uygulamanın derleme adı WebApp
'tır:
<link rel="stylesheet" href="WebApp.styles.css" />
Kapsamlı CSS dosyasında tanımlanan stiller yalnızca eşleşen dosyanın işlenmiş çıkışına uygulanır. Yukarıdaki örnekte, uygulamanın başka bir yerinde tanımlanan h1
CSS bildirimlerinin hiçbiri Index
başlık stiliyle çalışmaz. Kapsamlı CSS dosyaları için CSS stili basamaklandırma ve devralma kuralları etkin kalır. Örneğin doğrudan Index.cshtml
dosyasındaki <h1>
öğesine uygulanan stiller, Index.cshtml.css
dosyasındaki kapsamlı CSS dosyası stillerini geçersiz kılar.
Not
Paketleme gerçekleşirken CSS stili yalıtımını garanti etmek için CSS'nin Razor kod bloklarına aktarılması desteklenmez.
CSS yalıtımı yalnızca HTML öğeleri için geçerlidir. CSS yalıtımı Etiket Yardımcıları için desteklenmez.
Paketlenmiş CSS dosyası içinde her sayfa, görünüm veya Razor bileşeni b-{STRING}
biçiminde kapsam tanımlayıcısı ile ilişkilendirilir; burada {STRING}
yer tutucusu, çerçeve tarafından oluşturulan on karakterli bir dizedir. Aşağıdaki örnek Razor Pages uygulamasının Index
sayfasındaki önceki <h1>
öğesi için stili sağlar:
/* /Pages/Index.cshtml.rz.scp.css */
h1[b-3xxtam6d07] {
color: red;
}
Paketlenmiş dosyadan CSS stilinin uygulandığı Index
sayfasında, kapsam tanımlayıcısı bir HTML özniteliği olarak eklenir:
<h1 b-3xxtam6d07>
Tanımlayıcı bir uygulama için benzersizdir. Derleme zamanında {STATIC WEB ASSETS BASE PATH}/Project.lib.scp.css
kuralıyla bir proje paketi oluşturulur; burada {STATIC WEB ASSETS BASE PATH}
yer tutucusu, statik web varlıkları temel yoludur.
NuGet paketleri veya Razor sınıf kitaplıkları gibi başka projeler kullanılırsa, paketlenmiş dosya:
- CSS içeri aktarmalarını kullanarak stillere başvurur.
- Stilleri kullanan uygulamanın statik web varlığı olarak yayımlanmaz.
CSS ön işlemci desteği
CSS ön işlemcileri değişken, iç içe yerleştirme, modül, mixin ve devralma gibi özellikleri kullanarak CSS geliştirmeyi iyileştirmek için kullanışlıdır. CSS yalıtımı Sass veya Less gibi CSS ön işlemcilerini yerel olarak desteklemese de, ön işlemci derlemesi çerçevenin derleme işlemi sırasında CSS seçicileri yeniden yazmasından önce gerçekleştiği sürece, CSS ön işlemcileri sorunsuzca tümleştirilir. Örneğin Visual Studio'yu kullanarak mevcut ön işlemci derlemesini Visual Studio Görev Çalıştırıcı Gezgini'nde bir Derleme Öncesi görevi olarak yapılandırın.
AspNetCore.SassCompiler
gibi birçok üçüncü taraf NuGet paketi SASS/SCSS dosyalarını CSS yalıtımı gerçekleşmeden önce, derleme işleminin başlangıcında derleyebilir ve ek yapılandırma gerekmez.
CSS yalıtımı yapılandırması
CSS yalıtımı bazı gelişmiş senaryolarda, örneğin mevcut araçlara veya iş akışlarına bağımlılıklar olduğunda yapılandırmaya izin verir.
Kapsam tanımlayıcısının biçimini özelleştirme
Bu bölümde {Pages|Views}
yer tutucusu Razor Pages uygulamaları için Pages
veya MVC uygulamaları için Views
olur.
Varsayılan olarak kapsam tanımlayıcıları b-{STRING}
biçimini kullanır; burada {STRING}
yer tutucusu, çerçeve tarafından oluşturulan on karakterli bir dizedir. Kapsam tanımlayıcısının biçimini özelleştirmek için proje dosyasını istenen desene güncelleştirin:
<ItemGroup>
<None Update="{Pages|Views}/Index.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Yukarıdaki örnekte Index.cshtml.css
için oluşturulan CSS, b-{STRING}
olan kapsam tanımlayıcısını custom-scope-identifier
olarak değiştirir.
Kapsamlı CSS dosyalarıyla devralma özelliği elde etmek için kapsam tanımlayıcılarını kullanın. Aşağıdaki proje dosyası örneğinde, BaseView.cshtml.css
dosyası görünümler genelinde ortak olan stilleri içerir. DerivedView.cshtml.css
dosyası bu stilleri devralır.
<ItemGroup>
<None Update="{Pages|Views}/BaseView.cshtml.css" CssScope="custom-scope-identifier" />
<None Update="{Pages|Views}/DerivedView.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Kapsam tanımlayıcılarını birden çok dosyada paylaşmak için joker karakter (*
) işlecini kullanın:
<ItemGroup>
<None Update="{Pages|Views}/*.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Statik web varlıkları için temel yolu değiştirme
Kapsamlı CSS dosyası uygulamanın kökünde oluşturulur. Proje dosyasında varsayılan yolu değiştirmek için StaticWebAssetBasePath
özelliğini kullanın. Aşağıdaki örnek, kapsamlı CSS dosyasını ve rest uygulama varlıklarını _content
yola yerleştirir:
<PropertyGroup>
<StaticWebAssetBasePath>_content/$(PackageId)</StaticWebAssetBasePath>
</PropertyGroup>
Otomatik paketlemeyi devre dışı bırakma
Çerçevenin kapsamlı dosyaları çalışma zamanında yayımlamasını ve yüklemesini geri çevirmek için DisableScopedCssBundling
özelliğini kullanın. Bu özelliği kullanırken, yalıtılmış CSS dosyalarını obj
dizininden alma, çalışma zamanında bu dosyaları yayımlama ve yükleme görevleri diğer araçların veya işlemlerin sorumluluğundadır:
<PropertyGroup>
<DisableScopedCssBundling>true</DisableScopedCssBundling>
</PropertyGroup>
Razor sınıf kitaplığı (RCL) desteği
Razor sınıf kitaplığı (RCL) yalıtılmış stiller sağladığında, <link>
etiketinin href
özniteliği {STATIC WEB ASSET BASE PATH}/{PACKAGE ID}.bundle.scp.css
dosyasına işaret eder. Buradaki yer tutucular:
{STATIC WEB ASSET BASE PATH}
: Statik web varlığı temel yolu.{PACKAGE ID}
: Kitaplığın paket tanımlayıcısı. Proje dosyasında paket tanımlayıcısı belirtilmezse, paket tanımlayıcısı varsayılan olarak projenin derleme adını alır.
Aşağıdaki örnekte:
- Statik web varlığı temel yolu
_content/ClassLib
şeklindedir. - Sınıf kitaplığının derleme adı
ClassLib
şeklindedir.
Pages/Shared/_Layout.cshtml
(Razor Pages) veya Views/Shared/_Layout.cshtml
(MVC):
<link href="_content/ClassLib/ClassLib.bundle.scp.css" rel="stylesheet">
RCL'ler hakkında daha fazla bilgi için aşağıdaki makaleleri inceleyin:
- ASP.NET Core ile sınıf kitaplıklarında yeniden kullanılabilir Razor kullanıcı arabirimi
- ASP.NET Core Razor bileşenlerini bir Razor sınıf kitaplığından (RCL) kullanma
Blazor CSS yalıtımı hakkında bilgi için bkz. ASP.NET Core Blazor CSS yalıtımı.
OnGet işleyici geri dönüşü ile HEAD isteklerini işleme
HEAD
istekleri belirli bir kaynak için üst bilgileri almaya olanak tanır. GET
isteklerinden farklı olarak HEAD
istekleri bir yanıt gövdesi döndürmez.
Normal olarak HEAD
istekleri için bir OnHead
işleyicisi oluşturulur ve çağrılır:
public void OnHead()
{
HttpContext.Response.Headers.Add("Head Test", "Handled by OnHead!");
}
OnHead
işleyicisi tanımlanmadıysa, Razor Pages OnGet
işleyicisini çağırmaya geri döner.
XSRF/CSRF ve Razor Pages
Razor Pages Sahtecilik önleme doğrulaması ile korunur. FormTagHelper, HTML form öğelerine sahtecilik önleme belirteçleri ekler.
Razor Pages ile düzenleri, kısmi görünümleri, şablonları ve Etiket Yardımcılarını kullanma
Pages, Razor görünüm altyapısının tüm özellikleriyle çalışır. Düzenler, kısmi görünümler, şablonlar, Etiket Yardımcıları, _ViewStart.cshtml
ve _ViewImports.cshtml
geleneksel Razor görünümlerde olduğu gibi çalışır.
Şimdi bu özelliklerden bazılarından yararlanarak bu sayfanın karışıklığını azaltalım.
Pages/Shared/_Layout.cshtml
dosyasına bir düzen sayfası ekleyin:
<!DOCTYPE html>
<html>
<head>
<title>RP Sample</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
</head>
<body>
<a asp-page="/Index">Home</a>
<a asp-page="/Customers/Create">Create</a>
<a asp-page="/Customers/Index">Customers</a> <br />
@RenderBody()
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
</body>
</html>
- Her sayfanın düzenini denetler (sayfanın düzeni geri çevirmemiş olması koşuluyla).
- JavaScript ve stil sayfaları gibi HTML yapılarını içeri aktarır.
@RenderBody()
yönteminin çağrıldığı Razor sayfasının içeriği işlenir.
Daha fazla bilgi için bkz. Düzen sayfası.
Layout özelliği Pages/_ViewStart.cshtml
içinde ayarlanır:
@{
Layout = "_Layout";
}
Düzen, Pages/Shared klasöründe yer alır. Pages, geçerli sayfayla aynı klasörden başlayıp hiyerarşik olarak diğer görünümleri (düzenler, şablonlar, kısmi görünümler) arar. Pages/Shared klasöründeki düzen, Pages klasörünün altındaki herhangi bir Razor sayfasından kullanılabilir.
Düzen dosyası Pages/Shared klasöründe yer almalıdır.
Düzen dosyasını Views/Shared klasörüne koymamanızı öneririz. Views/Shared bir MVC görünümleri desenidir. Razor Pages'ın yok kurallarına değil klasör hiyerarşisine dayanması amaçlanmıştır.
Razor Sayfasından yapılan görünüm araması Pages klasörünü içerir. MVC denetleyicileri ve geleneksel Razor görünümleri ile kullanılan düzenler, şablonlar ve kısmi görünümler kullanılabilir.
Bir Pages/_ViewImports.cshtml
dosyası ekleyin:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@namespace
öğreticinin devamında açıklanmıştır. @addTagHelper
yönergesi, Pages klasöründeki tüm sayfalara yerleşik Etiket Yardımcılarını getirir.
Sayfada ayarlanan @namespace
yönergesi:
@page
@namespace RazorPagesIntro.Pages.Customers
@model NameSpaceModel
<h2>Name space</h2>
<p>
@Model.Message
</p>
@namespace
yönergesi sayfa için ad alanını ayarlar. @model
yönergesinin ad alanını içermesi gerekmez.
@namespace
yönergesi _ViewImports.cshtml
dosyasına eklendiğinde, belirtilen ad alanı @namespace
yönergesini içeri aktaran Sayfada oluşturulan ad alanı için ön ek sağlar. rest Oluşturulan ad alanının (sonek bölümü), içeren klasör ile sayfayı içeren _ViewImports.cshtml
klasör arasındaki noktayla ayrılmış göreli yoldur.
Örneğin PageModel
sınıfı Pages/Customers/Edit.cshtml.cs
açıkça ad alanını ayarlar:
namespace RazorPagesContacts.Pages
{
public class EditModel : PageModel
{
private readonly AppDbContext _db;
public EditModel(AppDbContext db)
{
_db = db;
}
// Code removed for brevity.
Dosya Pages/_ViewImports.cshtml
açıkça ad alanını ayarlar:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Pages/Customers/Edit.cshtml
Razor Sayfası için oluşturulan ad alanı PageModel
sınıfı ile aynıdır.
@namespace
ayrıca geleneksel Razor görünümlerle de çalışır.
Pages/Customers/Create.cshtml
görünüm dosyasını ele alalım:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Validation: customer name:</p>
<form method="post">
<div asp-validation-summary="ModelOnly"></div>
<span asp-validation-for="Customer!.Name"></span>
Name:
<input asp-for="Customer!.Name" />
<input type="submit" />
</form>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
_ViewImports.cshtml
ve önceki düzen dosyasıyla güncelleştirilmiş Pages/Customers/Create.cshtml
görünüm dosyası:
@page
@model CreateModel
<p>Enter a customer name:</p>
<form method="post">
Name:
<input asp-for="Customer!.Name" />
<input type="submit" />
</form>
Yukarıdaki kodda _ViewImports.cshtml
dosyası ad alanını ve Etiket Yardımcılarını içeri aktarmıştır. Düzen dosyası JavaScript dosyalarını içeri aktarmıştır.
Razor Pages başlangıç projesi, istemci tarafı doğrulaması ekleyen Pages/_ValidationScriptsPartial.cshtml
dosyasını içerir.
Kısmi görünümler hakkında daha fazla bilgi için bkz. ASP.NET Core'da kısmi görünümler.
Sayfalar için URL oluşturma
Daha önce gösterilen Create
sayfası RedirectToPage
kullanır:
public class CreateModel : PageModel
{
private readonly Data.CustomerDbContext _context;
public CreateModel(Data.CustomerDbContext context)
{
_context = context;
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public Customer? Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
if (Customer != null) _context.Customer.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
Uygulamanın dosya/klasör yapısı aşağıdaki gibidir:
/Pages
Index.cshtml
Privacy.cshtml
/Customers
Create.cshtml
Edit.cshtml
Index.cshtml
Pages/Customers/Create.cshtml
ve Pages/Customers/Edit.cshtml
sayfaları başarılı olduktan sonra Pages/Customers/Index.cshtml
konumuna yeniden yönlendirilir. ./Index
dizesi önceki sayfaya erişmek için kullanılan göreli sayfa adıdır. Pages/Customers/Index.cshtml
sayfasında URL'ler oluşturmak için kullanılır. Örneğin:
Url.Page("./Index", ...)
<a asp-page="./Index">Customers Index Page</a>
RedirectToPage("./Index")
Mutlak sayfa adı olan /Index
, Pages/Index.cshtml
sayfasına URL'ler oluşturmak için kullanılır. Örneğin:
Url.Page("/Index", ...)
<a asp-page="/Index">Home Index Page</a>
RedirectToPage("/Index")
Sayfa adı, baştaki /
ile birlikte /Pages kök klasöründen sayfaya giden yoldur (örneğin /Index
). Yukarıdaki URL oluşturma örnekleri, URL'yi sabit kodlamaya göre daha gelişmiş seçenekler ve işlevsel özellikler sunar. URL oluşturma işleminde yönlendirme kullanılır ve hedef yolda yönlendirmenin nasıl tanımlandığına göre parametreler oluşturulabilir ve kodlanabilir.
Sayfalar için URL oluşturma işleminde göreli adlar desteklenir. Aşağıdaki tabloda, Pages/Customers/Create.cshtml
dosyasında farklı RedirectToPage
parametreleri kullanılarak hangi Dizin sayfasının seçildiği gösterilir.
RedirectToPage(x) | Sayfa |
---|---|
RedirectToPage("/Index") | Pages/Index |
RedirectToPage("./Index"); | Pages/Customers/Index |
RedirectToPage("../Index") | Pages/Index |
RedirectToPage("Index") | Pages/Customers/Index |
RedirectToPage("Index")
, RedirectToPage("./Index")
ve RedirectToPage("../Index")
göreli adlardır. Hedef sayfanın adını hesaplamak için RedirectToPage
parametresi geçerli sayfanın yoluyla birleştirilir.
Karmaşık bir yapıya sahip siteler oluştururken göreli ad bağlama yararlı olur. Klasördeki sayfalar arasında bağlantı oluşturmak için göreli adlar kullanıldığında:
- Klasörün yeniden adlandırılması göreli bağlantıları kesmez.
- Bağlantılar klasör adını içermedikleri için kesilmez.
Sayfayı farklı bir Area hedefine yönlendirmek için alanı belirtin:
RedirectToPage("/Index", new { area = "Services" });
Daha fazla bilgi için bkz. ASP.NET Core'da alanlar ve ASP.NET Core'da Razor Pages yönlendirmesi ve uygulama kuralları.
ViewData özniteliği
Veriler ViewDataAttribute ile bir sayfaya geçirilebilir. [ViewData]
özniteliğine sahip özelliklerin değerleri ViewDataDictionary sınıfında depolanır ve buradan yüklenir.
Aşağıdaki örnekte AboutModel
Title
özelliğine [ViewData]
özniteliğini uygular:
public class AboutModel : PageModel
{
[ViewData]
public string Title { get; } = "About";
public void OnGet()
{
}
}
Hakkında sayfasında Title
özelliğine bir model özelliği olarak erişin:
<h1>@Model.Title</h1>
Düzende, title özelliği ViewData sözlüğünden okunur:
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"] - WebApplication</title>
...
TempData
ASP.NET Core TempData özelliğini kullanıma sunar. Bu özellik verileri okunana kadar depolar. Verileri silmeden incelemek için Keep ve Peek yönteleri kullanılabilir. TempData
, veriler birden fazla istek için gerekli olduğunda yeniden yönlendirme için kullanışlıdır.
Aşağıdaki kod TempData
özelliğini kullanarak Message
değerini ayarlar:
public class CreateDotModel : PageModel
{
private readonly AppDbContext _db;
public CreateDotModel(AppDbContext db)
{
_db = db;
}
[TempData]
public string Message { get; set; }
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
Message = $"Customer {Customer.Name} added";
return RedirectToPage("./Index");
}
}
Pages/Customers/Index.cshtml
dosyasında yer alan aşağıdaki işaretleme TempData
özelliğini kullanarak Message
değerini görüntüler.
<h3>Msg: @Model.Message</h3>
Pages/Customers/Index.cshtml.cs
sayfa modeli [TempData]
özniteliğini Message
özelliğine uygular.
[TempData]
public string Message { get; set; }
Daha fazla bilgi için bkz. TempData.
Sayfa başına birden çok işleyici
Aşağıdaki sayfa asp-page-handler
Etiket Yardımcısını kullanarak iki işleyici için işaretleme oluşturur:
@page
@model CreateFATHModel
<html>
<body>
<p>
Enter your name.
</p>
<div asp-validation-summary="All"></div>
<form method="POST">
<div><label>Name: <input asp-for="Customer.Name" /></label></div>
<!-- <snippet_Handlers> -->
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
<!-- </snippet_Handlers> -->
</form>
</body>
</html>
Yukarıdaki örnekte yer alan formun iki gönder düğmesi vardır ve bunlardan her biri FormActionTagHelper
kullanarak farklı bir URL'ye gönderir. asp-page-handler
özniteliği asp-page
özniteliğinin yardımcısıdır. asp-page-handler
, sayfa tarafından tanımlanan işleyici yöntemlerinin her birine gönderen URL'ler oluşturur. Örnek geçerli sayfaya bağlandığından asp-page
belirtilmez.
Sayfa modeli:
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesContacts.Data;
namespace RazorPagesContacts.Pages.Customers
{
public class CreateFATHModel : PageModel
{
private readonly AppDbContext _db;
public CreateFATHModel(AppDbContext db)
{
_db = db;
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostJoinListAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
public async Task<IActionResult> OnPostJoinListUCAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
Customer.Name = Customer.Name?.ToUpperInvariant();
return await OnPostJoinListAsync();
}
}
}
Yukarıdaki kod adlandırılmış işleyici yöntemleri kullanır. Adlandırılmış işleyici yöntemleri adın On<HTTP Verb>
öğesinden sonraki ve Async
öğesinden (varsa) önceki bölümündeki metin alınarak oluşturulur. Yukarıdaki örnekte sayfa yöntemleri OnPostJoinListAsync ve OnPostJoinListUCAsync'dir. OnPost ve Async kaldırıldığında işleyici adları JoinList
ve JoinListUC
olur.
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
Yukarıdaki kod kullanıldığında OnPostJoinListAsync
yöntemine gönderen URL yolu https://localhost:5001/Customers/CreateFATH?handler=JoinList
olur. OnPostJoinListUCAsync
yöntemine gönderen URL yolu https://localhost:5001/Customers/CreateFATH?handler=JoinListUC
şeklindedir.
Özel yollar
@page
yönergesini kullanarak:
- Sayfa için özel bir yol belirtin. Örneğin Hakkında sayfasının yolu
@page "/Some/Other/Path"
ile/Some/Other/Path
olarak ayarlanabilir. - Segmentleri sayfanın varsayılan yoluna ekleyin. Örneğin "item" segmenti
@page "item"
ile sayfanın varsayılan yoluna eklenebilir. - Parametreleri sayfanın varsayılan yoluna ekleyin. Örneğin
id
kimlik parametresi@page "{id}"
içeren bir sayfada gerekli olabilir.
Yolun başındaki bir tilde (~
) ile belirtilen köke göre yol desteklenir. Örneğin @page "~/Some/Other/Path"
ile @page "/Some/Other/Path"
aynıdır.
URL'de ?handler=JoinList
gibi sorgu dizelerinden hoşlanmıyorsanız işleyici adını URL'nin yol bölümüne yerleştirecek şekilde yolu değiştirin. Yol, @page
yönergesinden sonra çift tırnak içine alınmış bir yönlendirme şablonu eklenerek özelleştirilebilir.
@page "{handler?}"
@model CreateRouteModel
<html>
<body>
<p>
Enter your name.
</p>
<div asp-validation-summary="All"></div>
<form method="POST">
<div><label>Name: <input asp-for="Customer.Name" /></label></div>
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
</form>
</body>
</html>
Yukarıdaki kod kullanıldığında OnPostJoinListAsync
yöntemine gönderen URL yolu https://localhost:5001/Customers/CreateFATH/JoinList
olur. OnPostJoinListUCAsync
yöntemine gönderen URL yolu https://localhost:5001/Customers/CreateFATH/JoinListUC
şeklindedir.
handler
öğesini izleyen ?
, yönlendirme parametresinin isteğe bağlı olduğu anlamına gelir.
JavaScript (JS) dosyalarının birlikte yerleştirilmesi
Sayfalar ve görünümler için JavaScript (JS) dosyalarının birlikte yerleştirilmesi, uygulamadaki betikleri düzenlemenin kullanışlı bir yoludur.
Aşağıdaki dosya adı uzantısı kurallarını kullanarak JS dosyalarını aynı konuma yerleştirin:
- Razor Pages uygulamalarının sayfaları ve MVC uygulamalarının görünümleri:
.cshtml.js
. Örnekler:- Razor Pages uygulamasının
Pages/Index.cshtml
konumundakiIndex
sayfası içinPages/Index.cshtml.js
. - MVC uygulamasının
Views/Home/Index.cshtml
konumundakiIndex
görünümü içinViews/Home/Index.cshtml.js
.
- Razor Pages uygulamasının
Aynı konumda yer alan JS dosyaları, projedeki dosyanın yolu aracılığıyla genel olarak adreslenebilir:
Uygulamadaki bir birlikte bulunan betik dosyasındaki sayfalar ve görünümler:
{PATH}/{PAGE, VIEW, OR COMPONENT}.{EXTENSION}.js
{PATH}
yer tutucusu sayfanın, görünümün veya bileşenin yoludur.{PAGE, VIEW, OR COMPONENT}
yer tutucusu sayfa, görünüm veya bileşendir.{EXTENSION}
yer tutucusu sayfanın, görünümün veya bileşenin uzantısını eşleştirir (razor
veyacshtml
).
Razor Pages örneği:
Index
sayfası için bir JS dosyasıPages
klasöründe (Pages/Index.cshtml.js
)Index
sayfasının (Pages/Index.cshtml
) yanına yerleştirilir.Index
sayfasında,Pages
klasöründeki yolda betiğe başvurulur:@section Scripts { <script src="~/Pages/Index.cshtml.js"></script> }
Varsayılan düzen Pages/Shared/_Layout.cshtml
, birlikte bulunan JS dosyaları içerecek şekilde yapılandırılabilir ve bu da her sayfayı ayrı ayrı yapılandırma gereğini ortadan kaldırır:
<script asp-src-include="@(ViewContext.View.Path).js"></script>
Örnek indirme, varsayılan düzende birlikte bulunan JS dosyaları eklemek için önceki kod parçacığını kullanır.
Uygulama yayımlandığında çerçeve betiği otomatik olarak web köküne taşır. Yukarıdaki örnekte betik bin\Release\{TARGET FRAMEWORK MONIKER}\publish\wwwroot\Pages\Index.cshtml.js
konumuna taşınır; burada {TARGET FRAMEWORK MONIKER}
yer tutucusu Hedef Çerçeve Bilinen Adı'dır (TFM). Index
sayfasında betiğin göreli URL'sinde değişiklik yapmak gerekmez.
Uygulama yayımlandığında çerçeve betiği otomatik olarak web köküne taşır. Yukarıdaki örnekte betik bin\Release\{TARGET FRAMEWORK MONIKER}\publish\wwwroot\Components\Pages\Index.razor.js
konumuna taşınır; burada {TARGET FRAMEWORK MONIKER}
yer tutucusu Hedef Çerçeve Bilinen Adı'dır (TFM). Index
bileşeninde betiğin göreli URL'sinde değişiklik yapmak gerekmez.
Razor sınıf kitaplığı (RCL) tarafından sağlanan betikler için:
_content/{PACKAGE ID}/{PATH}/{PAGE, VIEW, OR COMPONENT}.{EXTENSION}.js
{PACKAGE ID}
yer tutucusu RCL'nin paket tanımlayıcısıdır (veya uygulama tarafından başvurulan bir sınıf kitaplığı için kitaplık adıdır).{PATH}
yer tutucusu sayfanın, görünümün veya bileşenin yoludur. RCL'nin köküne bir Razor bileşeni yerleştirilirse, yol segmenti eklenmez.{PAGE, VIEW, OR COMPONENT}
yer tutucusu sayfa, görünüm veya bileşendir.{EXTENSION}
yer tutucusu sayfanın, görünümün veya bileşenin uzantısını eşleştirir (razor
veyacshtml
).
Gelişmiş yapılandırma ve ayarlar
Aşağıdaki bölümlerde gösterilen yapılandırma ve ayarlar uygulamaların çoğunda gerekli değildir.
Gelişmiş seçenekleri yapılandırmak için RazorPagesOptions'ı yapılandıran AddRazorPages aşırı yüklemesini kullanın:
using Microsoft.EntityFrameworkCore;
using RazorPagesContacts.Data;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages(options =>
{
options.RootDirectory = "/MyPages";
options.Conventions.AuthorizeFolder("/MyPages/Admin");
});
builder.Services.AddDbContext<CustomerDbContext>(options =>
options.UseInMemoryDatabase("name"));
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Sayfalara kök dizin ayarlamak veya sayfalara uygulama modeli kuralları eklemek için RazorPagesOptions'ı kullanın. Kurallar hakkında daha fazla bilgi için bkz. Razor Pages yetkilendirme kuralları.
Görünümleri önceden derlemek için bkz. Razor görünümü derleme.
Razor Pages'ın içerik kökünde olduğunu belirtme
Varsayılan olarak Razor Pages'ın kökü /Pages dizinindedir. Razor Pages'ın uygulamanın içerik kökünde (ContentRootPath) olduğunu belirtmek için WithRazorPagesAtContentRoot ekleyin:
using Microsoft.EntityFrameworkCore;
using RazorPagesContacts.Data;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/MyPages/Admin");
})
.WithRazorPagesAtContentRoot();
builder.Services.AddDbContext<CustomerDbContext>(options =>
options.UseInMemoryDatabase("name"));
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Razor Pages'in özel kök dizininde olduğunu belirtme
Razor Pages'ın uygulamada özel bir kök dizinde olduğunu belirtmek için WithRazorPagesRoot ekleyin (göreli bir yol sağlayın):
using Microsoft.EntityFrameworkCore;
using RazorPagesContacts.Data;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/MyPages/Admin");
})
.WithRazorPagesRoot("/path/to/razor/pages");
builder.Services.AddDbContext<CustomerDbContext>(options =>
options.UseInMemoryDatabase("name"));
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Ek kaynaklar
- Bu girişi temel alan Razor Pages'ı kullanmaya başlama konusuna bakın.
- Yetkilendirme özniteliği ve Razor Pages
- Örnek kodu indirme veya görüntüleme
- ASP.NET Core'a Genel Bakış
- ASP.NET Core için Razor söz dizimi başvurusu
- ASP.NET Core'daki alanlar
- Öğretici: ASP.NET Core'da Razor Pages'i kullanmaya başlama
- ASP.NET Core'da Razor Pages yetkilendirme kuralları
- ASP.NET Core'da Razor Pages yönlendirme ve uygulama kuralları
- ASP.NET Core'da Razor Pages birim testleri
- ASP.NET Core'da kısmi görünümler
- Visual Studio 2019 16.4 ve üzeri ile ASP.NET ve web geliştirme iş yükü
- .NET Core 3.1 SDK
- Visual Studio 2019 16.8 ve üzeri ile ASP.NET ve web geliştirme iş yükü
- .NET 5.0 SDK
Razor Pages projesi oluşturma
Razor Pages projesi oluşturmaya yönelik ayrıntılı yönergeler için bkz. Razor Pages'ı kullanmaya başlama.
Razor Pages
Razor Pages Startup.cs
dosyasında etkinleştirilir:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
@page
<h1>Hello, world!</h1>
<h2>The time on the server is @DateTime.Now</h2>
Yukarıdaki kod, ASP.NET Core uygulamasında denetleyiciler ve görünümlerle kullanılan bir Razor görünüm dosyasına çok benzer. Bunu farklı kılan @page
yönergesidir. @page
dosyayı bir MVC eylemine dönüştürür. Bu da istekleri bir denetleyiciden geçmeden, doğrudan işlediği anlamına gelir. @page
, sayfadaki ilk Razor yönergesi olmalıdır. @page
diğer Razor yapılarının davranışını etkiler. Razor Pages dosya adlarının .cshtml
soneki vardır.
Aşağıdaki iki dosyada PageModel
sınıfının kullanıldığı benzer bir sayfa gösterilir. Pages/Index2.cshtml
dosyası:
@page
@using RazorPagesIntro.Pages
@model Index2Model
<h2>Separate page model</h2>
<p>
@Model.Message
</p>
Pages/Index2.cshtml.cs
sayfa modeli:
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System;
namespace RazorPagesIntro.Pages
{
public class Index2Model : PageModel
{
public string Message { get; private set; } = "PageModel in C#";
public void OnGet()
{
Message += $" Server time is { DateTime.Now }";
}
}
}
Kural gereği PageModel
sınıf dosyasının adı sonuna .cs
eklenmiş Razor Sayfa dosyasının adıyla aynıdır. Örneğin yukarıdaki Razor Sayfası Pages/Index2.cshtml
adını taşır. PageModel
sınıfını içeren dosya Pages/Index2.cshtml.cs
olarak adlandırılır.
URL yollarının sayfalarla ilişkileri, sayfanın dosya sistemindeki konumuna göre belirlenir. Aşağıdaki tabloda bir Razor Sayfa yolu ve eşleşen URL gösterilir:
Dosya adı ve yol | eşleşen URL |
---|---|
/Pages/Index.cshtml |
/ veya /Index |
/Pages/Contact.cshtml |
/Contact |
/Pages/Store/Contact.cshtml |
/Store/Contact |
/Pages/Store/Index.cshtml |
/Store veya /Store/Index |
Notlar:
- Çalışma zamanı Razor Pages dosyalarını varsayılan olarak Pages klasöründe arar.
- URL bir sayfa içermediğinde varsayılan sayfa
Index
sayfasıdır.
Temel form yazma
Razor Pages, web tarayıcıları tarafından kullanılan yaygın desenlerin uygulama oluşturulurken kolayca uygulanmasını sağlamak için tasarlanmıştır. Model bağlama, Etiket Yardımcıları ve HTML yardımcıları, Razor Sayfa sınıfında tanımlanan özelliklerle çalışır. Contact
modeli için temel bir "bize ulaşın" formu uygulayan bir sayfayı düşünün:
Bu belgedeki örnekler için Startup.cs dosyasında DbContext
başlatılır.
Bellek içi veritabanı Microsoft.EntityFrameworkCore.InMemory
NuGet paketini gerektirir.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CustomerDbContext>(options =>
options.UseInMemoryDatabase("name"));
services.AddRazorPages();
}
Veri modeli:
using System.ComponentModel.DataAnnotations;
namespace RazorPagesContacts.Models
{
public class Customer
{
public int Id { get; set; }
[Required, StringLength(10)]
public string Name { get; set; }
}
}
Veritabanı bağlamı:
using Microsoft.EntityFrameworkCore;
using RazorPagesContacts.Models;
namespace RazorPagesContacts.Data
{
public class CustomerDbContext : DbContext
{
public CustomerDbContext(DbContextOptions options)
: base(options)
{
}
public DbSet<Customer> Customers { get; set; }
}
}
Pages/Create.cshtml
görünüm dosyası:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Enter a customer name:</p>
<form method="post">
Name:
<input asp-for="Customer.Name" />
<input type="submit" />
</form>
Pages/Create.cshtml.cs
sayfa modeli:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesContacts.Data;
using RazorPagesContacts.Models;
using System.Threading.Tasks;
namespace RazorPagesContacts.Pages.Customers
{
public class CreateModel : PageModel
{
private readonly CustomerDbContext _context;
public CreateModel(CustomerDbContext context)
{
_context = context;
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Customers.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
Kurala göre PageModel
sınıfı <PageName>Model
olarak adlandırılır ve sayfayla aynı ad alanında yer alır.
PageModel
sınıfı, bir sayfanın mantığının sunumundan ayrılmasına olanak sağlar. Sayfaya gönderilen istekler için herhangi bir sayfa işleyicisini ve sayfayı işlemek için kullanılan verileri tanımlar. Bu ayrım şunları sağlar:
- Bağımlılık ekleme aracılığıyla sayfa bağımlılıklarını yönetme.
- Birim testi
Sayfada istekler üzerinde POST
(kullanıcı formu gönderdiğinde) çalışan bir OnPostAsync
işleyici yöntemi vardır. Herhangi bir HTTP fiili için işleyici yöntemleri eklenebilir. En yaygın işleyiciler şunlardır:
- Sayfa için gereken durumu başlatmak için
OnGet
. Yukarıdaki koddaOnGet
yöntemiCreateModel.cshtml
Razor Sayfasını görüntüler. - Form gönderilerini işlemek için
OnPost
.
Async
adlandırma son eki isteğe bağlıdır, ancak genellikle zaman uyumsuz işlevler için kural tarafından kullanılır. Yukarıdaki kod, Razor Pages için tipik bir koddur.
Denetleyicileri ve görünümleri kullanan ASP.NET uygulamalarını biliyorsanız:
- Yukarıdaki örnekte yer alan
OnPostAsync
kodu tipik bir denetleyici koduna benzer. - Model bağlama, doğrulama ve eylem sonuçları gibi MVC temel öğelerinin çoğu, Denetleyiciler ve Razor Pages ile aynı şekilde çalışır.
Yukarıdaki OnPostAsync
yöntemi:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Customers.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
OnPostAsync
temel akışı:
Doğrulama hatalarını denetleyin.
- Hata yoksa, verileri kaydedin ve yeniden yönlendirin.
- Hatalar varsa, doğrulama iletileriyle birlikte sayfayı yeniden gösterin. Çoğu durumda, doğrulama hataları istemci üzerinde algılanır ve sunucuya hiçbir zaman gönderilmez.
Pages/Create.cshtml
görünüm dosyası:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Enter a customer name:</p>
<form method="post">
Name:
<input asp-for="Customer.Name" />
<input type="submit" />
</form>
Pages/Create.cshtml
dosyasından işlenen HTML:
<p>Enter a customer name:</p>
<form method="post">
Name:
<input type="text" data-val="true"
data-val-length="The field Name must be a string with a maximum length of 10."
data-val-length-max="10" data-val-required="The Name field is required."
id="Customer_Name" maxlength="10" name="Customer.Name" value="" />
<input type="submit" />
<input name="__RequestVerificationToken" type="hidden"
value="<Antiforgery token here>" />
</form>
Yukarıdaki kodda formu gönderme:
Geçerli verilerle:
OnPostAsync
işleyici yöntemi RedirectToPage yardımcı yöntemini çağırır.RedirectToPage
, bir RedirectToPageResult örneği döndürür.RedirectToPage
:- Bir eylemin sonucudur.
RedirectToAction
veyaRedirectToRoute
yöntemine benzer (denetleyicilerde ve görünümlerde kullanılır).- Sayfalar için özelleştirilir. Yukarıdaki örnekte kök Dizin sayfasına yeniden yönlendirir (
/Index
).RedirectToPage
, Sayfalar için URL oluşturma bölümünde ayrıntılı olarak açıklanır.
Sunucuya geçirilen doğrulama hatalarıyla:
OnPostAsync
işleyici yöntemi Page yardımcı yöntemini çağırır.Page
, bir PageResult örneği döndürür. DöndürülenPage
, denetleyicilerdeki eylemlerinView
döndürmesine benzer.PageResult
, işleyici yöntemi için varsayılan dönüş türüdür.void
döndüren bir işleyici yöntemi sayfayı işler.- Yukarıdaki örnekte formu hiç değer olmadan göndermek ModelState.IsValid özelliğinin false döndürmesiyle sonuçlanır. Bu örnekte istemcide doğrulama hatası görüntülenmez. Doğrulama hatasının işlenmesi, bu belgenin ilerleyen bölümlerinde ele alınmıştır.
public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } _context.Customers.Add(Customer); await _context.SaveChangesAsync(); return RedirectToPage("./Index"); }
İstemci tarafı doğrulaması tarafından algılanan doğrulama hatalarıyla:
- Veriler sunucuya gönderilmez.
- İstemci tarafı doğrulaması, bu belgenin ilerleyen bölümlerinde açıklanmıştır.
Customer
özelliği model bağlamayı kabul etmek için [BindProperty]
özniteliğini kullanır:
public class CreateModel : PageModel
{
private readonly CustomerDbContext _context;
public CreateModel(CustomerDbContext context)
{
_context = context;
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Customers.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
[BindProperty]
, istemi tarafından değiştirilmemesi gereken özelliklerin bulunduğu modellerde kullanılmamalıdır. Daha fazla bilgi için bkz. Aşırı gönderim.
Razor Pages varsayılan olarak özellikleri yalnızca GET
dışındaki fiillerle bağlar. Özelliklere bağlama işlemi HTTP verilerini model türüne dönüştürmek üzere kod yazma gereğini ortadan kaldırır. Bağlama, form alanlarını işlemek ve girişi kabul etmek için aynı özelliği kullanarak (<input asp-for="Customer.Name">
) kodu azaltır.
Uyarı
Güvenlik nedeniyle GET
isteği verilerini sayfa modeli özelliklerine bağlamayı kabul etmeniz gerekir. Kullanıcı girişini özelliklere eşlemeden önce doğrulayın. Sorgu dizesi veya yönlendirme değerlerini kullanan senaryolarla ilgilenirken GET
bağlamasını kabul etmek yararlı olur.
GET
isteklerinde bir özelliği bağlamak için [BindProperty]
özniteliğinin SupportsGet
özelliğini true
olarak ayarlayın:
[BindProperty(SupportsGet = true)]
Daha fazla bilgi için bkz. ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Pages/Create.cshtml
görünüm dosyasını gözden geçirme:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Enter a customer name:</p>
<form method="post">
Name:
<input asp-for="Customer.Name" />
<input type="submit" />
</form>
- Önceki kodda , giriş etiketi yardımcısı
<input asp-for="Customer.Name" />
HTML<input>
öğesini model ifadesineCustomer.Name
bağlar. @addTagHelper
, Etiket Yardımcılarını kullanılabilir duruma getirir.
Sayfa home
Index.cshtml
home sayfa:
@page
@model RazorPagesContacts.Pages.Customers.IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<h1>Contacts home page</h1>
<form method="post">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var contact in Model.Customer)
{
<tr>
<td> @contact.Id </td>
<td>@contact.Name</td>
<td>
<!-- <snippet_Edit> -->
<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |
<!-- </snippet_Edit> -->
<!-- <snippet_Delete> -->
<button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button>
<!-- </snippet_Delete> -->
</td>
</tr>
}
</tbody>
</table>
<a asp-page="Create">Create New</a>
</form>
İlişkili PageModel
sınıfı (Index.cshtml.cs
):
public class IndexModel : PageModel
{
private readonly CustomerDbContext _context;
public IndexModel(CustomerDbContext context)
{
_context = context;
}
public IList<Customer> Customer { get; set; }
public async Task OnGetAsync()
{
Customer = await _context.Customers.ToListAsync();
}
public async Task<IActionResult> OnPostDeleteAsync(int id)
{
var contact = await _context.Customers.FindAsync(id);
if (contact != null)
{
_context.Customers.Remove(contact);
await _context.SaveChangesAsync();
}
return RedirectToPage();
}
}
Index.cshtml
dosyası aşağıdaki işaretlemeyi içerir:
<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |
Tutturucu <a /a>
Etiketi Yardımcısı , Düzenle sayfasına bağlantı oluşturmak için özniteliğini kullandı asp-route-{value}
. Bağlantı, kişi kimliğiyle birlikte yönlendirme verilerini içerir. Örneğin, https://localhost:5001/Edit/1
. Etiket Yardımcıları, Razor dosyalarında HTML öğelerinin oluşturulmasına ve işlenmesine sunucu tarafı kodun katılmasını etkinleştirir.
Index.cshtml
dosyası her müşteri kişisi için bir sil düğmesi oluşturmaya yönelik işaretleme içerir:
<button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button>
İşlenen HTML:
<button type="submit" formaction="/Customers?id=1&handler=delete">delete</button>
Sil düğmesi HTML'de işlendiğinde formaction öğesi şu parametreleri içerir:
asp-route-id
özniteliğiyle belirtilen müşteri kişi kimliği.asp-page-handler
özniteliğiyle belirtilenhandler
.
Düğme seçildiğinde sunucuya bir form POST
isteği gönderilir. Kurala göre işleyici yönteminin adı, OnPost[handler]Async
şemasına uygun olarak handler
parametresinin değeri temelinde seçilir.
Bu örnekte handler
delete
olduğundan, POST
isteğini işlemek için OnPostDeleteAsync
işleyici yöntemi kullanılır. asp-page-handler
farklı bir değere ayarlanırsa (örneğin remove
), OnPostRemoveAsync
adlı bir işleyici yöntemi seçilir.
public async Task<IActionResult> OnPostDeleteAsync(int id)
{
var contact = await _context.Customers.FindAsync(id);
if (contact != null)
{
_context.Customers.Remove(contact);
await _context.SaveChangesAsync();
}
return RedirectToPage();
}
OnPostDeleteAsync
yöntemi:
- Sorgu dizesinden
id
değerini alır. FindAsync
ile müşteri kişisi için veritabanını sorgular.- Müşteri kişisi bulunursa kaldırılır ve veritabanı güncelleştirilir.
- Kök Dizin sayfasını (
/Index
) yeniden yönlendirmek için RedirectToPage yöntemini çağırır.
Edit.cshtml dosyası
@page "{id:int}"
@model RazorPagesContacts.Pages.Customers.EditModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<h1>Edit Customer - @Model.Customer.Id</h1>
<form method="post">
<div asp-validation-summary="All"></div>
<input asp-for="Customer.Id" type="hidden" />
<div>
<label asp-for="Customer.Name"></label>
<div>
<input asp-for="Customer.Name" />
<span asp-validation-for="Customer.Name"></span>
</div>
</div>
<div>
<button type="submit">Save</button>
</div>
</form>
İlk satır @page "{id:int}"
yönergesini içerir. "{id:int}"
yönlendirme kısıtlaması sayfaya int
yönlendirme verilerini içeren istekleri kabul etmesini bildirir. Sayfaya yönelik istek int
öğesine dönüştürülebilecek yönlendirme verilerini içermiyorsa, çalışma zamanı bir HTTP 404 (bulunamadı) hatası döndürür. Kimliği isteğe bağlı yapmak için yönlendirme kısıtlamasının sonuna ?
ekleyin:
@page "{id:int?}"
Edit.cshtml.cs
dosyası:
public class EditModel : PageModel
{
private readonly CustomerDbContext _context;
public EditModel(CustomerDbContext context)
{
_context = context;
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnGetAsync(int id)
{
Customer = await _context.Customers.FindAsync(id);
if (Customer == null)
{
return RedirectToPage("./Index");
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(Customer).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
throw new Exception($"Customer {Customer.Id} not found!");
}
return RedirectToPage("./Index");
}
}
Doğrulama
Doğrulama kuralları:
- Model sınıfında bildirim temelli olarak belirtilir.
- Uygulamanın her yerinde zorlanır.
System.ComponentModel.DataAnnotations ad alanı, bir sınıfa veya özelliğe uygulanan bir dizi yerleşik doğrulama özniteliği sağlar. DataAnnotations biçimlendirmeye yardımcı olan ve hiçbir doğrulama sağlamayan [DataType]
gibi biçimlendirme öznitelikleri de içerir.
Customer
modelini ele alalım:
using System.ComponentModel.DataAnnotations;
namespace RazorPagesContacts.Models
{
public class Customer
{
public int Id { get; set; }
[Required, StringLength(10)]
public string Name { get; set; }
}
}
Aşağıdaki Create.cshtml
görünüm dosyasını kullanarak:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Validation: customer name:</p>
<form method="post">
<div asp-validation-summary="ModelOnly"></div>
<span asp-validation-for="Customer.Name"></span>
Name:
<input asp-for="Customer.Name" />
<input type="submit" />
</form>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
Yukarıdaki kod:
jQuery ve jQuery doğrulama betiklerini içerir.
<div />
Etkinleştirmek için ve<span />
Etiket Yardımcılarını kullanır:- İstemci tarafı doğrulaması.
- Doğrulama hatası işleme.
Aşağıdaki HTML'yi oluşturur:
<p>Enter a customer name:</p> <form method="post"> Name: <input type="text" data-val="true" data-val-length="The field Name must be a string with a maximum length of 10." data-val-length-max="10" data-val-required="The Name field is required." id="Customer_Name" maxlength="10" name="Customer.Name" value="" /> <input type="submit" /> <input name="__RequestVerificationToken" type="hidden" value="<Antiforgery token here>" /> </form> <script src="/lib/jquery/dist/jquery.js"></script> <script src="/lib/jquery-validation/dist/jquery.validate.js"></script> <script src="/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
Ad değeri olmadan Create form gönderilmesi, formda "Ad alanı zorunludur." hata iletisinin görüntülenmesine neden olur. İstemcide JavaScript etkinleştirildiyse tarayıcı hatayı sunucuya göndermeden görüntüler.
[StringLength(10)]
özniteliği işlenen HTML'de data-val-length-max="10"
oluşturur. data-val-length-max
, tarayıcıların belirtilen maksimum uzunluktan fazlasını girmesini önler. Gönderiyi düzenlemek ve yeniden yürütmek için Fiddler gibi bir araç kullanılırsa:
- 10 karakterden uzun bir ad ile.
- "Alan Adı uzunluk üst sınırı 10 olan bir dize olmalıdır." hata iletisi döndürülür.
Aşağıdaki Movie
modeli ele alalım:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace RazorPagesMovie.Models
{
public class Movie
{
public int ID { get; set; }
[StringLength(60, MinimumLength = 3)]
[Required]
public string Title { get; set; }
[Display(Name = "Release Date")]
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
[Column(TypeName = "decimal(18, 2)")]
public decimal Price { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z\s]*$")]
[Required]
[StringLength(30)]
public string Genre { get; set; }
[RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
[StringLength(5)]
[Required]
public string Rating { get; set; }
}
}
Doğrulama öznitelikleri, uygulandıkları model özelliklerinde zorlanacak davranışı belirtir:
Required
veMinimumLength
öznitelikleri özelliğin bir değer olması gerektiğini belirtir ama kullanıcının bu doğrulamaya uymak için boşluk girmesi engellenemez.RegularExpression
özniteliği girilebilecek karakterleri sınırlamak için kullanılır. Yukarıdaki kodda "Genre":- Yalnızca harfleri kullanmalıdır.
- İlk harfin büyük harf olması gerekir. Boşluk, sayı ve özel karakterlere izin verilmez.
RegularExpression
"Rating":- İlk karakterin büyük harf olmasını gerektirir.
- Sonraki alanlarda özel karakterlere ve sayılara izin verir. "PG-13" değeri Rating için geçerlidir ama "Genre" için başarısız olur.
Range
özniteliği, bir değeri belirtilen bir aralık içinde kısıtlar.StringLength
özniteliği bir dize özelliğinin boyut üst sınırını ve isteğe bağlı olarak boyut alt sınırını ayarlar.Değer türleri (
decimal
,int
,float
,DateTime
gibi) doğal olarak gereklidir ve[Required]
özniteliği gerekmez.
Movie
modeli için Create page, geçersiz değerleri içeren hatalar görüntüler:
Daha fazla bilgi için bkz.
OnGet işleyici geri dönüşü ile HEAD isteklerini işleme
HEAD
istekleri belirli bir kaynak için üst bilgileri almaya olanak tanır. GET
isteklerinden farklı olarak HEAD
istekleri bir yanıt gövdesi döndürmez.
Normal olarak HEAD
istekleri için bir OnHead
işleyicisi oluşturulur ve çağrılır:
public void OnHead()
{
HttpContext.Response.Headers.Add("Head Test", "Handled by OnHead!");
}
OnHead
işleyicisi tanımlanmadıysa, Razor Pages OnGet
işleyicisini çağırmaya geri döner.
XSRF/CSRF ve Razor Pages
Razor Pages Sahtecilik önleme doğrulaması ile korunur. FormTagHelper, HTML form öğelerine sahtecilik önleme belirteçleri ekler.
Razor Pages ile düzenleri, kısmi görünümleri, şablonları ve Etiket Yardımcılarını kullanma
Pages, Razor görünüm altyapısının tüm özellikleriyle çalışır. Düzenler, kısmi görünümler, şablonlar, Etiket Yardımcıları, _ViewStart.cshtml
ve _ViewImports.cshtml
geleneksel Razor görünümlerde olduğu gibi çalışır.
Şimdi bu özelliklerden bazılarından yararlanarak bu sayfanın karışıklığını azaltalım.
Pages/Shared/_Layout.cshtml
dosyasına bir düzen sayfası ekleyin:
<!DOCTYPE html>
<html>
<head>
<title>RP Sample</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
</head>
<body>
<a asp-page="/Index">Home</a>
<a asp-page="/Customers/Create">Create</a>
<a asp-page="/Customers/Index">Customers</a> <br />
@RenderBody()
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
</body>
</html>
- Her sayfanın düzenini denetler (sayfanın düzeni geri çevirmemiş olması koşuluyla).
- JavaScript ve stil sayfaları gibi HTML yapılarını içeri aktarır.
@RenderBody()
yönteminin çağrıldığı Razor sayfasının içeriği işlenir.
Daha fazla bilgi için bkz. Düzen sayfası.
Layout özelliği Pages/_ViewStart.cshtml
içinde ayarlanır:
@{
Layout = "_Layout";
}
Düzen, Pages/Shared klasöründe yer alır. Pages, geçerli sayfayla aynı klasörden başlayıp hiyerarşik olarak diğer görünümleri (düzenler, şablonlar, kısmi görünümler) arar. Pages/Shared klasöründeki düzen, Pages klasörünün altındaki herhangi bir Razor sayfasından kullanılabilir.
Düzen dosyası Pages/Shared klasöründe yer almalıdır.
Düzen dosyasını Views/Shared klasörüne koymamanızı öneririz. Views/Shared bir MVC görünümleri desenidir. Razor Pages'ın yok kurallarına değil klasör hiyerarşisine dayanması amaçlanmıştır.
Razor Sayfasından yapılan görünüm araması Pages klasörünü içerir. MVC denetleyicileri ve geleneksel Razor görünümleri ile kullanılan düzenler, şablonlar ve kısmi görünümler kullanılabilir.
Bir Pages/_ViewImports.cshtml
dosyası ekleyin:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@namespace
öğreticinin devamında açıklanmıştır. @addTagHelper
yönergesi, Pages klasöründeki tüm sayfalara yerleşik Etiket Yardımcılarını getirir.
Sayfada ayarlanan @namespace
yönergesi:
@page
@namespace RazorPagesIntro.Pages.Customers
@model NameSpaceModel
<h2>Name space</h2>
<p>
@Model.Message
</p>
@namespace
yönergesi sayfa için ad alanını ayarlar. @model
yönergesinin ad alanını içermesi gerekmez.
@namespace
yönergesi _ViewImports.cshtml
dosyasına eklendiğinde, belirtilen ad alanı @namespace
yönergesini içeri aktaran Sayfada oluşturulan ad alanı için ön ek sağlar. rest Oluşturulan ad alanının (sonek bölümü), içeren klasör ile sayfayı içeren _ViewImports.cshtml
klasör arasındaki noktayla ayrılmış göreli yoldur.
Örneğin PageModel
sınıfı Pages/Customers/Edit.cshtml.cs
açıkça ad alanını ayarlar:
namespace RazorPagesContacts.Pages
{
public class EditModel : PageModel
{
private readonly AppDbContext _db;
public EditModel(AppDbContext db)
{
_db = db;
}
// Code removed for brevity.
Dosya Pages/_ViewImports.cshtml
açıkça ad alanını ayarlar:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Pages/Customers/Edit.cshtml
Razor Sayfası için oluşturulan ad alanı PageModel
sınıfı ile aynıdır.
@namespace
ayrıca geleneksel Razor görünümlerle de çalışır.
Pages/Create.cshtml
görünüm dosyasını ele alalım:
@page
@model RazorPagesContacts.Pages.Customers.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<p>Validation: customer name:</p>
<form method="post">
<div asp-validation-summary="ModelOnly"></div>
<span asp-validation-for="Customer.Name"></span>
Name:
<input asp-for="Customer.Name" />
<input type="submit" />
</form>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
_ViewImports.cshtml
ve önceki düzen dosyasıyla güncelleştirilmiş Pages/Create.cshtml
görünüm dosyası:
@page
@model CreateModel
<p>Enter a customer name:</p>
<form method="post">
Name:
<input asp-for="Customer.Name" />
<input type="submit" />
</form>
Yukarıdaki kodda _ViewImports.cshtml
dosyası ad alanını ve Etiket Yardımcılarını içeri aktarmıştır. Düzen dosyası JavaScript dosyalarını içeri aktarmıştır.
Razor Pages başlangıç projesi, istemci tarafı doğrulaması ekleyen Pages/_ValidationScriptsPartial.cshtml
dosyasını içerir.
Kısmi görünümler hakkında daha fazla bilgi için bkz. ASP.NET Core'da kısmi görünümler.
Sayfalar için URL oluşturma
Daha önce gösterilen Create
sayfası RedirectToPage
kullanır:
public class CreateModel : PageModel
{
private readonly CustomerDbContext _context;
public CreateModel(CustomerDbContext context)
{
_context = context;
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Customers.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
Uygulamanın dosya/klasör yapısı aşağıdaki gibidir:
/Pages
Index.cshtml
Privacy.cshtml
/Customers
Create.cshtml
Edit.cshtml
Index.cshtml
Pages/Customers/Create.cshtml
ve Pages/Customers/Edit.cshtml
sayfaları başarılı olduktan sonra Pages/Customers/Index.cshtml
konumuna yeniden yönlendirilir. ./Index
dizesi önceki sayfaya erişmek için kullanılan göreli sayfa adıdır. Pages/Customers/Index.cshtml
sayfasında URL'ler oluşturmak için kullanılır. Örneğin:
Url.Page("./Index", ...)
<a asp-page="./Index">Customers Index Page</a>
RedirectToPage("./Index")
Mutlak sayfa adı olan /Index
, Pages/Index.cshtml
sayfasına URL'ler oluşturmak için kullanılır. Örneğin:
Url.Page("/Index", ...)
<a asp-page="/Index">Home Index Page</a>
RedirectToPage("/Index")
Sayfa adı, baştaki /
ile birlikte /Pages kök klasöründen sayfaya giden yoldur (örneğin /Index
). Yukarıdaki URL oluşturma örnekleri, URL'yi sabit kodlamaya göre daha gelişmiş seçenekler ve işlevsel özellikler sunar. URL oluşturma işleminde yönlendirme kullanılır ve hedef yolda yönlendirmenin nasıl tanımlandığına göre parametreler oluşturulabilir ve kodlanabilir.
Sayfalar için URL oluşturma işleminde göreli adlar desteklenir. Aşağıdaki tabloda, Pages/Customers/Create.cshtml
dosyasında farklı RedirectToPage
parametreleri kullanılarak hangi Dizin sayfasının seçildiği gösterilir.
RedirectToPage(x) | Sayfa |
---|---|
RedirectToPage("/Index") | Pages/Index |
RedirectToPage("./Index"); | Pages/Customers/Index |
RedirectToPage("../Index") | Pages/Index |
RedirectToPage("Index") | Pages/Customers/Index |
RedirectToPage("Index")
, RedirectToPage("./Index")
ve RedirectToPage("../Index")
göreli adlardır. Hedef sayfanın adını hesaplamak için RedirectToPage
parametresi geçerli sayfanın yoluyla birleştirilir.
Karmaşık bir yapıya sahip siteler oluştururken göreli ad bağlama yararlı olur. Klasördeki sayfalar arasında bağlantı oluşturmak için göreli adlar kullanıldığında:
- Klasörün yeniden adlandırılması göreli bağlantıları kesmez.
- Bağlantılar klasör adını içermedikleri için kesilmez.
Sayfayı farklı bir Area hedefine yönlendirmek için alanı belirtin:
RedirectToPage("/Index", new { area = "Services" });
Daha fazla bilgi için bkz. ASP.NET Core'da alanlar ve ASP.NET Core'da Razor Pages yönlendirmesi ve uygulama kuralları.
ViewData özniteliği
Veriler ViewDataAttribute ile bir sayfaya geçirilebilir. [ViewData]
özniteliğine sahip özelliklerin değerleri ViewDataDictionary sınıfında depolanır ve buradan yüklenir.
Aşağıdaki örnekte AboutModel
Title
özelliğine [ViewData]
özniteliğini uygular:
public class AboutModel : PageModel
{
[ViewData]
public string Title { get; } = "About";
public void OnGet()
{
}
}
Hakkında sayfasında Title
özelliğine bir model özelliği olarak erişin:
<h1>@Model.Title</h1>
Düzende, title özelliği ViewData sözlüğünden okunur:
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"] - WebApplication</title>
...
TempData
ASP.NET Core TempData özelliğini kullanıma sunar. Bu özellik verileri okunana kadar depolar. Verileri silmeden incelemek için Keep ve Peek yönteleri kullanılabilir. TempData
, veriler birden fazla istek için gerekli olduğunda yeniden yönlendirme için kullanışlıdır.
Aşağıdaki kod TempData
özelliğini kullanarak Message
değerini ayarlar:
public class CreateDotModel : PageModel
{
private readonly AppDbContext _db;
public CreateDotModel(AppDbContext db)
{
_db = db;
}
[TempData]
public string Message { get; set; }
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
Message = $"Customer {Customer.Name} added";
return RedirectToPage("./Index");
}
}
Pages/Customers/Index.cshtml
dosyasında yer alan aşağıdaki işaretleme TempData
özelliğini kullanarak Message
değerini görüntüler.
<h3>Msg: @Model.Message</h3>
Pages/Customers/Index.cshtml.cs
sayfa modeli [TempData]
özniteliğini Message
özelliğine uygular.
[TempData]
public string Message { get; set; }
Daha fazla bilgi için bkz. TempData.
Sayfa başına birden çok işleyici
Aşağıdaki sayfa asp-page-handler
Etiket Yardımcısını kullanarak iki işleyici için işaretleme oluşturur:
@page
@model CreateFATHModel
<html>
<body>
<p>
Enter your name.
</p>
<div asp-validation-summary="All"></div>
<form method="POST">
<div><label>Name: <input asp-for="Customer.Name" /></label></div>
<!-- <snippet_Handlers> -->
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
<!-- </snippet_Handlers> -->
</form>
</body>
</html>
Yukarıdaki örnekte yer alan formun iki gönder düğmesi vardır ve bunlardan her biri FormActionTagHelper
kullanarak farklı bir URL'ye gönderir. asp-page-handler
özniteliği asp-page
özniteliğinin yardımcısıdır. asp-page-handler
, sayfa tarafından tanımlanan işleyici yöntemlerinin her birine gönderen URL'ler oluşturur. Örnek geçerli sayfaya bağlandığından asp-page
belirtilmez.
Sayfa modeli:
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesContacts.Data;
namespace RazorPagesContacts.Pages.Customers
{
public class CreateFATHModel : PageModel
{
private readonly AppDbContext _db;
public CreateFATHModel(AppDbContext db)
{
_db = db;
}
[BindProperty]
public Customer Customer { get; set; }
public async Task<IActionResult> OnPostJoinListAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_db.Customers.Add(Customer);
await _db.SaveChangesAsync();
return RedirectToPage("/Index");
}
public async Task<IActionResult> OnPostJoinListUCAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
Customer.Name = Customer.Name?.ToUpperInvariant();
return await OnPostJoinListAsync();
}
}
}
Yukarıdaki kod adlandırılmış işleyici yöntemleri kullanır. Adlandırılmış işleyici yöntemleri adın On<HTTP Verb>
öğesinden sonraki ve Async
öğesinden (varsa) önceki bölümündeki metin alınarak oluşturulur. Yukarıdaki örnekte sayfa yöntemleri OnPostJoinListAsync ve OnPostJoinListUCAsync'dir. OnPost ve Async kaldırıldığında işleyici adları JoinList
ve JoinListUC
olur.
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
Yukarıdaki kod kullanıldığında OnPostJoinListAsync
yöntemine gönderen URL yolu https://localhost:5001/Customers/CreateFATH?handler=JoinList
olur. OnPostJoinListUCAsync
yöntemine gönderen URL yolu https://localhost:5001/Customers/CreateFATH?handler=JoinListUC
şeklindedir.
Özel yollar
@page
yönergesini kullanarak:
- Sayfa için özel bir yol belirtin. Örneğin Hakkında sayfasının yolu
@page "/Some/Other/Path"
ile/Some/Other/Path
olarak ayarlanabilir. - Segmentleri sayfanın varsayılan yoluna ekleyin. Örneğin "item" segmenti
@page "item"
ile sayfanın varsayılan yoluna eklenebilir. - Parametreleri sayfanın varsayılan yoluna ekleyin. Örneğin
id
kimlik parametresi@page "{id}"
içeren bir sayfada gerekli olabilir.
Yolun başındaki bir tilde (~
) ile belirtilen köke göre yol desteklenir. Örneğin @page "~/Some/Other/Path"
ile @page "/Some/Other/Path"
aynıdır.
URL'de ?handler=JoinList
gibi sorgu dizelerinden hoşlanmıyorsanız işleyici adını URL'nin yol bölümüne yerleştirecek şekilde yolu değiştirin. Yol, @page
yönergesinden sonra çift tırnak içine alınmış bir yönlendirme şablonu eklenerek özelleştirilebilir.
@page "{handler?}"
@model CreateRouteModel
<html>
<body>
<p>
Enter your name.
</p>
<div asp-validation-summary="All"></div>
<form method="POST">
<div><label>Name: <input asp-for="Customer.Name" /></label></div>
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
</form>
</body>
</html>
Yukarıdaki kod kullanıldığında OnPostJoinListAsync
yöntemine gönderen URL yolu https://localhost:5001/Customers/CreateFATH/JoinList
olur. OnPostJoinListUCAsync
yöntemine gönderen URL yolu https://localhost:5001/Customers/CreateFATH/JoinListUC
şeklindedir.
handler
öğesini izleyen ?
, yönlendirme parametresinin isteğe bağlı olduğu anlamına gelir.
Gelişmiş yapılandırma ve ayarlar
Aşağıdaki bölümlerde gösterilen yapılandırma ve ayarlar uygulamaların çoğunda gerekli değildir.
Gelişmiş seçenekleri yapılandırmak için RazorPagesOptions'ı yapılandıran AddRazorPages aşırı yüklemesini kullanın:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.RootDirectory = "/MyPages";
options.Conventions.AuthorizeFolder("/MyPages/Admin");
});
}
Sayfalara kök dizin ayarlamak veya sayfalara uygulama modeli kuralları eklemek için RazorPagesOptions'ı kullanın. Kurallar hakkında daha fazla bilgi için bkz. Razor Pages yetkilendirme kuralları.
Görünümleri önceden derlemek için bkz. Razor görünümü derleme.
Razor Pages'ın içerik kökünde olduğunu belirtme
Varsayılan olarak Razor Pages'ın kökü /Pages dizinindedir. Razor Pages'ın uygulamanın içerik kökünde (ContentRootPath) olduğunu belirtmek için WithRazorPagesAtContentRoot ekleyin:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/MyPages/Admin");
})
.WithRazorPagesAtContentRoot();
}
Razor Pages'in özel kök dizininde olduğunu belirtme
Razor Pages'ın uygulamada özel bir kök dizinde olduğunu belirtmek için WithRazorPagesRoot ekleyin (göreli bir yol sağlayın):
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/MyPages/Admin");
})
.WithRazorPagesRoot("/path/to/razor/pages");
}
Ek kaynaklar
- Bu girişi temel alan Razor Pages'ı kullanmaya başlama konusuna bakın.
- Yetkilendirme özniteliği ve Razor Pages
- Örnek kodu indirme veya görüntüleme
- ASP.NET Core'a Genel Bakış
- ASP.NET Core için Razor söz dizimi başvurusu
- ASP.NET Core'daki alanlar
- Öğretici: ASP.NET Core'da Razor Pages'i kullanmaya başlama
- ASP.NET Core'da Razor Pages yetkilendirme kuralları
- ASP.NET Core'da Razor Pages yönlendirme ve uygulama kuralları
- ASP.NET Core'da Razor Pages birim testleri
- ASP.NET Core'da kısmi görünümler
ASP.NET Core