Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Rick Anderson, Dave Brock ve Kirk Larkin
Note
Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 10 sürümüne bakın.
Warning
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 9 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 makalede Sayfalar'ın sayfa odaklı web uygulamaları oluşturmak için etkili olmasını sağlayan Razor mimari, kavramlar ve desenler ele alınmaktadır. Sayfalar'ın nasıl Razor çalıştığını, temel bileşenlerini ve uygulama için en iyi yöntemleri açıklar. Adım adım yönergelerle uygulamalı öğrenmeyi tercih ediyorsanız bkz. Öğretici: ASP.NET Core ile Sayfalar web uygulaması oluşturmaRazor. ASP.NET Core'a genel bir bakış için bkz. ASP.NET Core'a giriş.
Prerequisites
- Visual Studio 2022 ile ASP.NET ve web geliştirme iş yükü.
- .NET 6 SDK
Razor Pages projesi oluşturma
Razor Sayfa
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 Razor arabirimine IEndpointRouteBuilder 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 Razor eklenmiş .cs 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 |
Notes:
- Çalışma zamanı Razor Pages dosyalarını varsayılan olarak Pages klasöründe arar.
- URL bir sayfa içermediğinde varsayılan sayfa
Indexsayfası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 OnPostAsync (kullanıcı formu gönderdiğinde) çalışan bir POST 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 koddaOnGetyöntemiCreate.cshtmlRazor 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
OnPostAsynckodu 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:
OnPostAsyncişleyici yöntemi RedirectToPage yardımcı yöntemini çağırır.RedirectToPage, bir RedirectToPageResult örneği döndürür.RedirectToPage:- Bir eylemin sonucudur.
-
RedirectToActionveyaRedirectToRouteyö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:
-
OnPostAsynciş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 eylemlerinViewdöndürmesine benzer.PageResult, işleyici yöntemi için varsayılan dönüş türüdür.voiddö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.
Warning
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.Namebağlar. -
@addTagHelper, Etiket Yardımcılarını kullanılabilir duruma getirir.
Giriş sayfası
Index.cshtml giriş sayfasıdır:
@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. -
handlerözniteliğiyle belirtilenasp-page-handler.
Düğme seçildiğinde sunucuya bir form POST isteği gönderilir. Kurala göre işleyici yönteminin adı, handler şemasına uygun olarak OnPost[handler]Async parametresinin değeri temelinde seçilir.
Bu örnekte handlerdelete olduğundan, OnPostDeleteAsync isteğini işlemek için POST 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
iddeğerini alır. -
FindAsyncile 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ı (RedirectToPage) yeniden yönlendirmek için
/Indexyö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);
}
}
Validation
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ğrulama.
- 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:
RequiredveMinimumLengthö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,DateTimegibi) 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 izolasyonu
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.css dosyasının adıyla eşleşen bir yardımcı .cshtml dosyasına yerleştirir. Aşağıdaki örnekte, yalnızca Index.cshtml.css sayfası ya da görünümüne CSS stillerini sağlayan bir Index.cshtml 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 <head> (Pages/Shared/_Layout.cshtml Pages) veya Razor (MVC) dosyasının Views/Shared/_Layout.cshtml 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 <h1> dosyasındaki Index.cshtml öğesine uygulanan stiller, Index.cshtml.css dosyasındaki kapsamlı CSS dosyası stillerini geçersiz kılar.
Note
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 <h1> Pages uygulamasının Index sayfasındaki önceki Razor öğ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 Pages Pages uygulamaları için Razor 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, kapsamı belirlenmiş CSS dosyasını ve uygulamanın varlıklarının geri kalanını _content yoluna 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 OnHead istekleri için bir HEAD işleyicisi oluşturulur ve çağrılır:
public void OnHead()
{
HttpContext.Response.Headers.Add("Head Test", "Handled by OnHead!");
}
Razor işleyicisi tanımlanmadıysa, OnGet Pages OnHead 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.
dosyasına bir Pages/Shared/_Layout.cshtml 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.
-
Razor yönteminin çağrıldığı
@RenderBody()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, Razor klasörünün altındaki herhangi bir 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. Oluşturulan ad alanının kalan kısmı (sonek bölümü), _ViewImports.cshtml içeren klasör ile sayfayı içeren klasör arasındaki noktalarla 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>
Pages/Customers/Create.cshtml ve önceki düzen dosyasıyla güncelleştirilmiş _ViewImports.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.cshtmlPrivacy.cshtml/Customers
Create.cshtmlEdit.cshtmlIndex.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 / 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, RedirectToPage dosyasında farklı Pages/Customers/Create.cshtml parametreleri kullanılarak hangi Dizin sayfasının seçildiği gösterilir.
| RedirectToPage(x) | Page |
|---|---|
| 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[ViewData] özelliğine Title ö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 Message özelliğini kullanarak TempData 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 Message özelliğini kullanarak TempData 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
/Some/Other/Pathile@page "/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
idkimlik 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.
? öğesini izleyen handler, 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. Examples:-
Pages/Index.cshtml.jsPages uygulamasınınIndexkonumundaki Razor sayfası içinPages/Index.cshtml. - MVC uygulamasının
Views/Home/Index.cshtml.jskonumundakiIndexgörünümü içinViews/Home/Index.cshtml.
-
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 (razorveyacshtml).
Razor Pages örneği:
JS sayfası için bir
IndexdosyasıPagesklasöründe (Pages/Index.cshtml.js)Indexsayfasının (Pages/Index.cshtml) yanına yerleştirilir.Indexsayfasında,Pagesklasö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 (razorveyacshtml).
-
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 AddRazorPages'ı yapılandıran RazorPagesOptions 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. WithRazorPagesAtContentRoot Pages'ın uygulamanın Razor () olduğunu belirtmek için ContentRootPath 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
WithRazorPagesRoot Pages'ın uygulamada özel bir kök dizinde olduğunu belirtmek için Razor 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 SDK
Razor Pages projesi oluşturma
Razor Sayfa
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 Razor eklenmiş .cs 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 |
Notes:
- Çalışma zamanı Razor Pages dosyalarını varsayılan olarak Pages klasöründe arar.
- URL bir sayfa içermediğinde varsayılan sayfa
Indexsayfası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ı, Sayfa sınıfında tanımlanan özelliklerle Razor.
Contact modeli için temel bir "bize ulaşın" formu uygulayan bir sayfayı düşünün:
Bu belgedeki örnekler için DbContext dosyasında 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 OnPostAsync (kullanıcı formu gönderdiğinde) çalışan bir POST 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 koddaOnGetyöntemiCreateModel.cshtmlRazor 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
OnPostAsynckodu 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:
OnPostAsyncişleyici yöntemi RedirectToPage yardımcı yöntemini çağırır.RedirectToPage, bir RedirectToPageResult örneği döndürür.RedirectToPage:- Bir eylemin sonucudur.
-
RedirectToActionveyaRedirectToRouteyö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:
-
OnPostAsynciş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 eylemlerinViewdöndürmesine benzer.PageResult, işleyici yöntemi için varsayılan dönüş türüdür.voiddö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.
Warning
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.Namebağlar. -
@addTagHelper, Etiket Yardımcılarını kullanılabilir duruma getirir.
Giriş sayfası
Index.cshtml giriş sayfasıdır:
@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. -
handlerözniteliğiyle belirtilenasp-page-handler.
Düğme seçildiğinde sunucuya bir form POST isteği gönderilir. Kurala göre işleyici yönteminin adı, handler şemasına uygun olarak OnPost[handler]Async parametresinin değeri temelinde seçilir.
Bu örnekte handlerdelete olduğundan, OnPostDeleteAsync isteğini işlemek için POST 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
iddeğerini alır. -
FindAsyncile 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ı (RedirectToPage) yeniden yönlendirmek için
/Indexyö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");
}
}
Validation
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ğrulama.
- 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:
RequiredveMinimumLengthö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,DateTimegibi) 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 OnHead istekleri için bir HEAD işleyicisi oluşturulur ve çağrılır:
public void OnHead()
{
HttpContext.Response.Headers.Add("Head Test", "Handled by OnHead!");
}
Razor işleyicisi tanımlanmadıysa, OnGet Pages OnHead 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.
dosyasına bir Pages/Shared/_Layout.cshtml 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.
-
Razor yönteminin çağrıldığı
@RenderBody()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, Razor klasörünün altındaki herhangi bir 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. Oluşturulan ad alanının kalan kısmı (sonek bölümü), _ViewImports.cshtml içeren klasör ile sayfayı içeren klasör arasındaki noktalarla 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>
Pages/Create.cshtml ve önceki düzen dosyasıyla güncelleştirilmiş _ViewImports.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.cshtmlPrivacy.cshtml/Customers
Create.cshtmlEdit.cshtmlIndex.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 / 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, RedirectToPage dosyasında farklı Pages/Customers/Create.cshtml parametreleri kullanılarak hangi Dizin sayfasının seçildiği gösterilir.
| RedirectToPage(x) | Page |
|---|---|
| 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[ViewData] özelliğine Title ö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 Message özelliğini kullanarak TempData 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 Message özelliğini kullanarak TempData 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
/Some/Other/Pathile@page "/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
idkimlik 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.
? öğesini izleyen handler, 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 AddRazorPages'ı yapılandıran RazorPagesOptions 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. WithRazorPagesAtContentRoot Pages'ın uygulamanın Razor () olduğunu belirtmek için ContentRootPath 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
WithRazorPagesRoot Pages'ın uygulamada özel bir kök dizinde olduğunu belirtmek için Razor 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