RazorASP.NET Core'de Sayfalara Giriş

Rick Anderson ve Ryan Nowak

Razor Sayfalar, sayfa odaklı senaryoları kodlamayı denetleyiciler ve görünümler kullanmaya göre daha kolay ve daha üretken hale getirir.

Model-View-Controller yaklaşımını kullanan bir öğretici arıyorsanız bkz. MVC Kullanmaya başlayın ile ASP.NET Core.

Bu belge, Sayfalar'a giriş Razor sağlar. Bu adım adım bir öğretici değildir. Bazı bölümlerin çok gelişmiş olduğunu görüyorsanız bkz. Kullanmaya başlayın Razor ile ekleme. Uygulama görünümüne genel ASP.NET Core için bkz.ASP.NET Core.

Önkoşullar

Sayfalar Razor projesi oluşturma

Sayfalar Kullanmaya başlayın hakkında Razor ayrıntılı yönergeler için bkz. Sayfalar ile Razor çalışma.

Razor Sayfa

RazorSayfalar Startup.cs'de etkindir:

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();
        });
    }
}

Temel bir sayfayı göz önünde bulun:

@page

<h1>Hello, world!</h1>
<h2>The time on the server is @DateTime.Now</h2>

Yukarıdaki kod, denetleyiciler ve Razor görünümler ile bir ASP.NET Core kullanılan bir görünüm dosyasına çok benzer. Bunu farklı kılan, @page yönergedir. @page dosyayı bir MVC eylemine dönüştürerek istekleri denetleyiciden geçene kadar doğrudan işlemesi anlamına gelir. @page , bir sayfanın Razor ilk yönergesi olması gerekir. @page diğer yapıların Razor davranışını etkiler. Razor Sayfalar dosya adlarının bir .cshtml soneki vardır.

Aşağıdaki iki dosyada PageModel da benzer bir sayfa, sınıfı kullanılarak 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ı .cs ekli Razor Sayfa dosyası ile aynı adı içerir. Örneğin, önceki Sayfa Razor Pages/Index2.cshtml'dir. sınıfını içeren dosya PageModel Pages/Index2.cshtml.cs olarak adlandırılmıştır.

URL yollarının sayfalarla olan ilişkilendirmeleri, dosya sistemi içinde sayfanın konumu tarafından belirlenir. Aşağıdaki tabloda bir Sayfa yolu Razor ve eşleşen URL'si yer alır:

Dosya adı ve yolu 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ı varsayılan Razor olarak Sayfalar klasöründe Sayfalar dosyalarını aramaz.
  • Index , URL sayfa eklemezse varsayılan sayfadır.

Temel bir form yazma

Razor Sayfalar, web tarayıcıları ile kullanılan yaygın desenlerin uygulama oluştururken uygulanmasını kolaylaştıran şekilde tasarlanmıştır. Model bağlama, Etiket Yardımcılarıve HTML yardımcılarının hepsi yalnızca Bir Sayfa sınıfında tanımlanan Razor özelliklerle çalışır. Model için temel bir "bize ulaşın" formunu uygulayan bir sayfa Contact düşünün:

Bu belgede yer alan örnekler DbContext için, Startup.cs dosyasında başlatılır.

Bellekte veritabanı için NuGet Microsoft.EntityFrameworkCore.InMemory gerekir.

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");
        }
    }
}

Kural gereği sınıfı PageModel <PageName>Model çağrılır ve sayfayla aynı ad alanı içindedir.

sınıfı, PageModel bir sayfanın mantığının sunumundan ayrılmasına olanak sağlar. Sayfaya gönderilen istekler için sayfa işleyicilerini ve sayfayı işlemek için kullanılan verileri tanımlar. Bu ayrım şunları sağlar:

Sayfada istekler OnPostAsync üzerinde çalışan bir işleyici POST yöntemi vardır (kullanıcı formu yayınlasa). 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 kodda yöntemi OnGet CreateModel.cshtml Sayfasını Razor 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, Sayfalar için Razor tipiktir.

Denetleyiciler ve görünümler ASP.NET uygulamaları kullanma hakkında bilgi sahibiysiniz:

  • Yukarıdaki OnPostAsync örnekteki kod, tipik denetleyici koduna benzer şekilde görünüyor.
  • Model bağlama, doğrulama ve eylem sonuçlarıgibi MVC temellerinin çoğu Denetleyiciler ve Sayfalar ile aynı Razor şekilde çalışır.

Önceki OnPostAsync yöntem:

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

    _context.Customers.Add(Customer);
    await _context.SaveChangesAsync();

    return RedirectToPage("./Index");
}

temel OnPostAsync akışı:

Doğrulama hatalarını denetleyin.

  • Hata yoksa verileri kaydedin ve yeniden yönlendirmeyi kullanın.
  • Hatalar varsa doğrulama iletileriyle sayfayı yeniden gösterebilirsiniz. Ç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'den 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>

Önceki kodda şu formu gönderebilirsiniz:

  • Geçerli verilerle:

    • İşleyici OnPostAsync yöntemi yardımcı yöntemini RedirectToPage çağıran. RedirectToPage, bir RedirectToPageResult örneği döndürür. RedirectToPage:

      • Bir eylem sonucu.
      • veya ile RedirectToAction RedirectToRoute benzerdir (denetleyicilerde ve görünümlerde kullanılır).
      • Sayfalar için özelleştirilebilir. Yukarıdaki örnekte kök Dizin sayfasına () yeniden /Index yönlendirildi. RedirectToPage, Sayfalar için URL oluşturma bölümünde ayrıntılı olarak açıktır.
  • Sunucuya geçirilen doğrulama hatalarına sahip:

    • İşleyici OnPostAsync yöntemi yardımcı yöntemini Page çağıran. Page, bir PageResult örneği döndürür. Geri Page dönüş, denetleyicilerde eylemlerin döndürerek döndüren eylemlere View benzer. PageResult , bir işleyici yöntemi için varsayılan dönüş türüdür. Döndüren bir işleyici yöntemi void sayfayı işler.
    • Yukarıdaki örnekte, formun hiçbir değer olmadan nakledilmesi ModelState ile sonuçlanır. IsValid yanlış döndürüyor. Bu örnekte, istemcide hiçbir doğrulama hatası gösterilmezler. Doğrulama hatası teslim etme 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 birlikte:

    • Veriler sunucuya nakledilmedi.
    • İstemci tarafı doğrulaması bu belgenin ilerleyen kısımlarında açıklanmıştır.

CustomerÖzelliği, [BindProperty] model bağlamasını kabul etmek için ö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]istemci tarafından değiştirilmemesi gereken özellikler içeren modellerde kullanılmamalıdır. Daha fazla bilgi için bkz. fazla nakil.

Razor Sayfalar, varsayılan olarak, özellikleri yalnızca fiil dışı özelliklerle bağlayın GET . Özelliklere bağlama, HTTP verilerini model türüne dönüştürmek için kod yazma ihtiyacını ortadan kaldırır. Bağlama, form alanlarını işlemek için aynı özelliği kullanarak kodu azaltır ( <input asp-for="Customer.Name"> ) ve girişi kabul eder.

Uyarı

Güvenlik nedeniyle, istek verilerini sayfa modeli GET özelliklerine bağlamayı kabul edebilirsiniz. Kullanıcı girişini özelliklere eşlemeden önce doğrulayın. Bağlamayı GET kabul etmek, sorgu dizesi veya yol değerlerine bağlı senaryoları ele almak için kullanışlıdır.

İsteklerde bir özelliği GET bağlamak için [BindProperty] özniteliğin özelliğini olarak SupportsGet true ayarlayın:

[BindProperty(SupportsGet = true)]

Daha fazla bilgi için bkz. ASP.NET Çekirdek Topluluk Standup: GET tartışmalarını bağlama (YouTube).

Sayfalar/oluşturma. cshtml görünüm dosyası gözden geçiriliyor:

@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>
  • Yukarıdaki kodda, giriş etiketi Yardımcısı <input asp-for="Customer.Name" /> HTML <input> öğesini Customer.Name model ifadesine bağlar.
  • @addTagHelper Etiket Yardımcıları kullanılabilir hale 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>
                        <a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |
                        <button type="submit" asp-page-handler="delete"
                                asp-route-id="@contact.Id">delete
                        </button>
                    </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 biçimlendirmeyi içerir:

<td>

<a /a> Tutturucu etiketi Yardımcısı , asp-route-{value} düzenleme sayfasına bir bağlantı oluşturmak için özniteliğini kullandı. Bağlantı, iletişim KIMLIĞINE sahip rota verileri içerir. Örneğin, https://localhost:5001/Edit/1. Etiket Yardımcıları , sunucu tarafı kodun dosyalarda HTML öğeleri oluşturma ve işlemeye katılmasını sağlar Razor .

Index. cshtml dosyası her müşteri için bir silme düğmesi oluşturmak için biçimlendirme içerir:

<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |
<button type="submit" asp-page-handler="delete"

İşlenmiş HTML:

<button type="submit" formaction="/Customers?id=1&amp;handler=delete">delete</button>

Sil düğmesi HTML 'de işlendiğinde, bu nesnenin biçimlendirme parametreleri içerir:

  • Özniteliği tarafından belirtilen müşteri iletişim KIMLIĞI asp-route-id .
  • , handler Özniteliği tarafından belirtilen asp-page-handler .

Düğme seçildiğinde, sunucuya bir form POST isteği gönderilir. Kurala göre, işleyici yönteminin adı, handler şemaya göre parametrenin değerine göre seçilir OnPost[handler]Async .

handler delete Bu örnekte olduğundan, OnPostDeleteAsync isteği işlemek için işleyici yöntemi kullanılır POST . , Gibi asp-page-handler farklı bir değere ayarlandıysa, remove adında bir işleyici yöntemi OnPostRemoveAsync 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();
}

OnPostDeleteAsyncYöntemi:

  • idSorgu dizesinden alır.
  • Müşteri iletişim için veritabanını sorgular FindAsync .
  • Müşteri ilgili kişisi bulunursa, kaldırılır ve veritabanı güncelleştirilir.
  • RedirectToPageKök dizin sayfasına () yeniden yönlendirmek için çağrılar /Index .

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. Yönlendirme kısıtlaması, "{id:int}" sayfada yönlendirme verileri içeren sayfaya istekleri kabul etmesini söyler int . Sayfaya yapılan bir istek öğesine dönüştürülebileceği rota verileri içermiyorsa int , çalışma zamanı BIR HTTP 404 (bulunamadı) hatası döndürür. KIMLIĞI isteğe bağlı yapmak için ? yol kısıtlamasına 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 bildirimli olarak belirtilir.
  • Uygulamada her yerde zorlanır.

System.ComponentModel.DataAnnotationsAd alanı, bir sınıfa veya özelliğe bildirimli olarak uygulanan bir yerleşik doğrulama öznitelikleri kümesi sağlar. Dataaçıklamalarda, [DataType] biçimlendirme ile ilgili yardım ve herhangi bir doğrulama sağlamayan gibi biçimlendirme öznitelikleri de bulunur.

Modeli göz önünde bulundurun Customer :

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 betikleri içerir.

  • <div />' İ <span /> etkinleştirmek için ve Etiket Yardımcıları 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>
    

Create formunu ad değeri olmadan göndermek "ad alanı gereklidir" hata iletisini görüntüler. formunda. İstemcide JavaScript etkinse tarayıcı, sunucuya göndermeden hatayı görüntüler.

[StringLength(10)]Özniteliği data-val-length-max="10" işlenmiş html üzerinde oluşturulur. data-val-length-max tarayıcıların belirtilen uzunluk üst sınırından fazlasını girmesini engeller. Gönderiyi düzenlemek ve yeniden oynatmak için Fiddler gibi bir araç kullanılıyorsa:

  • , Adı 10 ' dan daha uzun.
  • "Alan adı, en fazla 10 uzunluğunda bir dize olmalıdır" hata iletisi. hatası döndürülür.

Aşağıdaki modeli göz önünde bulundurun Movie :

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, uygulanan model özellikleri üzerinde zorlamak için davranışı belirtir:

  • RequiredVe MinimumLength öznitelikleri bir özelliğin bir değere sahip olması gerektiğini gösterir, ancak hiçbir şey, kullanıcının bu doğrulamayı karşılamak için boşluk girmesini engeller.

  • RegularExpressionÖznitelik, hangi karakterlerin girişi yapabileceğini sınırlamak için kullanılır. Yukarıdaki kodda, "tarz":

    • Yalnızca harfler kullanılmalıdır.
    • İlk harfin büyük harfle olması gerekir. Boşluk, sayı ve özel karakterlere izin verilmez.
  • RegularExpression"Derecelendirme":

    • İlk karakterin büyük harf olmasını gerektirir.
    • Sonraki boşlukların içindeki özel karakter ve sayılara izin verir. "PG-13" bir derecelendirme için geçerlidir, ancak bir "tarz" 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 uzunluk üst sınırını ve isteğe bağlı olarak en düşük uzunluğunu ayarlar.

  • Değer türleri (örneğin,,, decimal int ), doğal olarak float DateTime gereklidir ve özniteliğe gerek kalmaz [Required] .

Model için Oluştur sayfasında, Movie geçersiz değerlere sahip hatalar görüntülenir:

Birden çok jQuery istemci tarafı doğrulama hatası içeren film görünümü formu

Daha fazla bilgi için bkz.

OnGet işleyicisi geri dönüşü ile tanıtıcı HEAD istekleri

HEAD istekler belirli bir kaynak için üstbilgileri almaya izin verir. GETİsteklerin aksine HEAD istekler bir yanıt gövdesi döndürmez.

Normalde, OnHead istekler için bir işleyici oluşturulur ve çağırılır HEAD :

public void OnHead()
{
    HttpContext.Response.Headers.Add("Head Test", "Handled by OnHead!");
}

Razor Bir OnGet işleyici tanımlanmazsa, sayfa işleyiciyi çağırmaya geri döner OnHead .

XSRF/CSRF ve Razor Sayfalar

Razor Sayfalar, Antiforgery doğrulamasıtarafından korunur. Formtaghelper , antiforgery belirteçlerini HTML form öğelerine çıkartır.

Sayfalarla düzenleri, partileri, şablonları ve etiket yardımcıları kullanma Razor

Sayfalar, görünüm altyapısının tüm özellikleri ile çalışır Razor . Düzenler, partıals, şablonlar, etiket yardımcıları, _ViewStart. cshtml ve _ViewImports. cshtml geleneksel görünümlerde aynı şekilde çalışır Razor .

Bu özelliklerden bazılarının avantajlarından yararlanarak bu sayfayı declutter edelim.

Pages/Shared/_Layout.cshtml'ye 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>

Düzen:

  • Her sayfanın düzenini (sayfa düzeni devre dışı bırakmadıkça) kontrol eder.
  • JavaScript ve stil sayfaları gibi HTML yapılarını içeri aktarıyor.
  • Sayfanın içeriği Razor çağrılarak @RenderBody() 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 Sayfalar/Paylaşılan klasöründedir. Sayfalar, geçerli sayfayla aynı klasörden başlayarak diğer görünümleri (düzenler, şablonlar, kısmi öğeler) hiyerarşik olarak aratır. Sayfalar/Paylaşılan klasöründeki bir düzen, Sayfalar klasörünün Razor altındaki herhangi bir sayfadan kullanılabilir.

Düzen dosyası Sayfalar/Paylaşılan klasörüne iner.

Düzen dosyasını Görünümler/Paylaşılan klasörüne koymamanız önerilir. Görünümler/Paylaşılan bir MVC görünüm desenidir. Razor Sayfalar, yol kurallarına değil klasör hiyerarşisini dayandırarak kullanılır.

Sayfalar klasörünü içeren Razor bir Sayfadan arama görüntüleme. MVC denetleyicileri ve geleneksel görünümlerle kullanılan düzenler, şablonlar ve kısmiler Razor yalnızca çalışır.

Pages/_ViewImports.cshtml dosyası ekleyin:

@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

@namespace öğreticinin sonraki adımlarında açıklanmıştır. @addTagHelperyönergesi yerleşik Etiket Yardımcılarını Sayfalar klasöründeki tüm sayfalara getirir.

Sayfada @namespace ayarlanmış yönerge:

@page
@namespace RazorPagesIntro.Pages.Customers

@model NameSpaceModel

<h2>Name space</h2>
<p>
    @Model.Message
</p>

@namespaceyönergesi, sayfa için ad alanını ayarlar. yönergesi @model ad alanını içermesine gerek yok.

yönergesi @namespace _ViewImports.cshtml içinde olduğunda, belirtilen ad alanı yönergeyi içeri aktaran Sayfada oluşturulan ad alanı için ön eki @namespace sağlar. Oluşturulan ad alanının geri kalanı (sonek bölümü), _ViewImports.cshtml dosyasını içeren klasör ile sayfayı içeren klasör arasındaki noktayla ayrılmış göreli yoldur.

Örneğin, PageModel Pages/Customers/Edit.cshtml.cs sınıfı ad alanını açıkça ayarlar:

namespace RazorPagesContacts.Pages
{
    public class EditModel : PageModel
    {
        private readonly AppDbContext _db;

        public EditModel(AppDbContext db)
        {
            _db = db;
        }

        // Code removed for brevity.

Pages/_ViewImports.cshtml dosyası aşağıdaki ad alanını ayarlar:

@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Pages/Customers/Edit.cshtml Sayfası için oluşturulan ad Razor alanı sınıfıyla PageModel aynıdır.

@namespacegeleneksel görünümlerle de Razor çalışır.

Pages/Create.cshtml görünüm dosyasını göz önünde bulundurabilirsiniz:

@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ı ile 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 ad alanını ve Etiket Yardımcılarını içe aktardı. Düzen dosyası JavaScript dosyalarını içe aktardı.

Sayfalar Razor başlangıç projesi, istemci tarafı doğrulamayı _ValidationScriptsPartial Pages/_ValidationScriptsPartial.cshtml dosyasını içerir.

Kısmi görünümler hakkında daha fazla bilgi için ASP.NET Core'de kısmi görünümler bkz. .

Sayfalar için URL oluşturma

Daha Create önce gösterilen sayfa 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");
    }
}

Uygulama aşağıdaki dosya/klasör yapısına sahiptir:

  • /Pages

    • Index.cshtml

    • Privacy.cshtml

    • /Customers

      • Create.cshtml
      • Edit.cshtml
      • Index.cshtml

Pages/Customers/Create.cshtml ve Pages/Customers/Edit.cshtml sayfaları başarıdan sonra Pages/Customers/Index.cshtml sayfasına yeniden yönlendirmektedir. Dize, ./Index önceki sayfaya erişmek için kullanılan göreli bir sayfa adıdır. Sayfalar/Müşteriler/Index.cshtml sayfasına URL oluşturmak için kullanılır. Örnek:

  • Url.Page("./Index", ...)
  • <a asp-page="./Index">Customers Index Page</a>
  • RedirectToPage("./Index")

Mutlak sayfa /Index adı, Pages/Index.cshtml sayfasının URL'lerini oluşturmak için kullanılır. Örnek:

  • Url.Page("/Index", ...)
  • <a asp-page="/Index">Home Index Page</a>
  • RedirectToPage("/Index")

Sayfa adı, kök /Pages klasöründen bir baştaki (örneğin, ) sayfanın / /Index yoludur. Önceki URL oluşturma örnekleri, BIR URL'yi sabit kodlamaya göre gelişmiş seçenekler ve işlevsel özellikler sunar. URL oluşturma yönlendirmeyi kullanır ve yolun hedef yolda nasıl tanımlandığına göre parametreler üretin ve kodlayabilir.

Sayfalar için URL oluşturma, göreli adları destekler. Aşağıdaki tabloda RedirectToPage Sayfalar/Müşteriler/Create.cshtml içinde farklı parametreler kullanılarak hangi Dizin sayfasının seçilecekleri listelemektedir.

RedirectToPage(x) Sayfa
RedirectToPage("/Index") Sayfalar/Dizin
RedirectToPage("./Index"); Sayfalar/Müşteriler/Dizin
RedirectToPage(".. /Index") Sayfalar/Dizin
RedirectToPage("Index") Sayfalar/Müşteriler/Dizin

RedirectToPage("Index"), RedirectToPage("./Index") ve RedirectToPage("../Index") göreli adlarıdır. RedirectToPageparametresi, hedef sayfanın adını hesaplamak için geçerli sayfanın yoluyla birleştirilmiştir.

Göreli ad bağlama, karmaşık bir yapıya sahip siteler inşası için kullanışlıdır. Bir klasördeki sayfalar arasında bağlantı için göreli adlar kullanılırken:

  • Bir klasörü yeniden adı, göreli bağlantıları bozmaz.
  • Klasör adını içermeleri nedeniyle bağlantılar bozuk değildir.

Farklı bir Alanda bir sayfaya yeniden yönlendirmek içinalanı belirtin:

RedirectToPage("/Index", new { area = "Services" });

Daha fazla bilgi için ASP.NET Core bölgeler ve RazorSayfalarda yönlendirme ve uygulama kuralları ASP.NET Core bölümlerine bakın.

ViewData özniteliği

Veriler ile bir sayfaya ViewDataAttribute geçirebilirsiniz. özniteliğine sahip [ViewData] özellikler, değerlerini depolar ve 'den ViewDataDictionary yüklenir.

Aşağıdaki örnekte, AboutModel [ViewData] özniteliğini özelliğine Title uygular:

public class AboutModel : PageModel
{
    [ViewData]
    public string Title { get; } = "About";

    public void OnGet()
    {
    }
}

Hakkında sayfasında, özelliğine Title model özelliği olarak erişin:

<h1>@Model.Title</h1>

Düzende başlık ViewData sözlüğünden okunur:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>@ViewData["Title"] - WebApplication</title>
    ...

TempData

ASP.NET Core , 'i açığa TempData çıkarır. Bu özellik, okunana kadar verileri depolar. ve Keep Peek yöntemleri, verileri silinmeden incelemek için kullanılabilir. TempData , tek bir istekten daha fazla veri gerektiğinde yeniden yönlendirme için kullanışlıdır.

Aşağıdaki kod, değerini kullanarak Message TempData 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ındaki aşağıdaki işaretleme, kullanarak değerini Message TempData görüntüler.

<h3>Msg: @Model.Message</h3>

Pages/Customers/Index.cshtml.cs sayfa modeli [TempData] özniteliğini özelliğine Message uygular.

[TempData]
public string Message { get; set; }

Daha fazla bilgi için bkz. TempData.

Sayfa başına birden çok işleyici

Aşağıdaki sayfada Etiket Yardımcısı kullanılarak iki işleyici için asp-page-handler işaretleme oluşturulur:

@page
@model CreateFATHModel

<html>
<body>
    <p>
        Enter your name.
    </p>
    <div asp-validation-summary="All"></div>
    <form method="POST">
        <div>Name: <input asp-for="Customer.Name" /></div>
        <input type="submit" asp-page-handler="JoinList" value="Join" />
        <input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
    </form>
</body>
</html>

Önceki örnekteki formda, her biri farklı bir URL'ye göndermek için kullanan FormActionTagHelper iki gönderme düğmesi vardır. özniteliği, asp-page-handler için bir asp-page yardımcıdır. asp-page-handler , bir sayfa tarafından tanımlanan her bir işleyici yöntemine gönderme URL'leri üretir. asp-page belirtilmez çünkü örnek geçerli sayfaya bağlantı sağlar.

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öntemlerini kullanır. Adlandırılmış işleyici yöntemleri, adından sonra ve (varsa) önce metni On<HTTP Verb> alarak Async oluşturulur. Yukarıdaki örnekte, sayfa yöntemleri OnPost JoinList Async ve OnPost JoinListUC Async'tir. OnPost ve Async kaldırılarak işleyici adları ve JoinList JoinListUC olur.

<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />

Önceki kodu kullanarak, adresine gönderilen URL yolu OnPostJoinListAsync https://localhost:5001/Customers/CreateFATH?handler=JoinList olur. adresine gönderilen URL OnPostJoinListUCAsync https://localhost:5001/Customers/CreateFATH?handler=JoinListUC yoludur.

Özel yollar

Yönergeyi @page kullanarak şunları yapmak için:

  • Sayfaya özel bir yol belirtin. Örneğin Hakkında sayfasına giden yol ile olarak ayarlanmış /Some/Other/Path @page "/Some/Other/Path" olabilir.
  • Segmentleri sayfanın varsayılan yolunun sonuna ekleyin. Örneğin, bir "öğe" segmenti ile sayfanın varsayılan yoluna @page "item" eklenebilir.
  • Parametreleri sayfanın varsayılan yolunun sonuna ekleyin. Örneğin, kimlik parametresi, id ile bir sayfa için gerekli @page "{id}" olabilir.

Yolun başındaki bir tilde ( ) tarafından belirlenen kök göreli ~ yol de desteklenmeli. Örneğin, @page "~/Some/Other/Path" ile @page "/Some/Other/Path" aynıdır.

URL'de sorgu dizesini tercih ediyorsanız, işleyici adını URL'nin yol bölümüne ?handler=JoinList koymak için yolu değiştirebilirsiniz. Yol, yönergeden sonra çift tırnak içine alınmış bir yol şablonu ekilerek @page özelleştirilebilir.

@page "{handler?}"
@model CreateRouteModel

<html>
<body>
    <p>
        Enter your name.
    </p>
    <div asp-validation-summary="All"></div>
    <form method="POST">
        <div>Name: <input asp-for="Customer.Name" /></div>
        <input type="submit" asp-page-handler="JoinList" value="Join" />
        <input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
    </form>
</body>
</html>

Önceki kodu kullanarak, adresine gönderilen URL yolu OnPostJoinListAsync https://localhost:5001/Customers/CreateFATH/JoinList olur. adresine gönderilen URL OnPostJoinListUCAsync https://localhost:5001/Customers/CreateFATH/JoinListUC yoludur.

Aşağıdaki, ? handler yol parametresinin isteğe bağlı olduğu anlamına gelir.

Gelişmiş yapılandırma ve ayarlar

Aşağıdaki bölümlerde yer alan yapılandırma ve ayarlar çoğu uygulama için gerekli değildir.

Gelişmiş seçenekleri yapılandırmak için AddRazorPages yapılandıran aşırı yüklemeyi RazorPagesOptions kullanın:

public void ConfigureServices(IServiceCollection services)
{            
    services.AddRazorPages(options =>
    {
        options.RootDirectory = "/MyPages";
        options.Conventions.AuthorizeFolder("/MyPages/Admin");
    });
}

Sayfaların RazorPagesOptions kök dizinini ayarlamak veya sayfalar için uygulama modeli kuralları eklemek için kullanın. Kural hakkında daha fazla bilgi için Razor bkz. Sayfalar yetkilendirme kuralları.

Görünümleri önceden derlemek için bkz. Razor derlemeyi görüntüleme.

Sayfaların Razor içerik kökünde olduğunu belirtme

Varsayılan olarak, Razor Sayfalar'ın kökü /Pages dizinindedir. Sayfalarınızı WithRazorPagesAtContentRoot uygulamanın Razor içerik kökünde ( ) belirtmek için ContentRootPath ekleyin:

public void ConfigureServices(IServiceCollection services)
{            
    services.AddRazorPages(options =>
        {
            options.Conventions.AuthorizeFolder("/MyPages/Admin");
        })
        .WithRazorPagesAtContentRoot();
}

Sayfaların Razor özel bir kök dizinde olduğunu belirtme

Sayfalar'ın uygulama içinde özel bir kök dizinde olduğunu belirtmek için ekleyin WithRazorPagesRoot Razor (göreli bir yol belirtin):

public void ConfigureServices(IServiceCollection services)
{            
    services.AddRazorPages(options =>
        {
            options.Conventions.AuthorizeFolder("/MyPages/Admin");
        })
        .WithRazorPagesRoot("/path/to/razor/pages");
}

Ek kaynaklar

Uyarı

Visual Studio 2017 kullanıyorsanız, #3124 ile çalışmayan .NET Core SDK hakkında bilgi için dotnet/sdk sorun Visual Studio.

Sayfalar Razor projesi oluşturma

Sayfalar Kullanmaya başlayın oluşturma Razor hakkında ayrıntılı yönergeler için bkz. Sayfalar ile Razor çalışma.

Razor Sayfa

RazorSayfalar Startup.cs'de etkindir:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Includes support for Razor Pages and controllers.
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMvc();
    }
}

Temel bir sayfayı göz önünde bulun:

@page

<h1>Hello, world!</h1>
<h2>The time on the server is @DateTime.Now</h2>

Yukarıdaki kod, denetleyiciler ve Razor görünümler ile bir ASP.NET Core kullanılan bir görünüm dosyasına çok benzer. Bunu farklı kılan, @page yönergedir. @page dosyayı bir MVC eylemine dönüştürerek istekleri denetleyiciden geçene kadar doğrudan işlemesi anlamına gelir. @page , bir sayfanın Razor ilk yönergesi olması gerekir. @page diğer yapıların Razor davranışını etkiler.

Aşağıdaki iki dosyada PageModel da benzer bir sayfa, sınıfı kullanılarak gösterilir. Pages/Index2.cshtml dosyası:

@page
@using RazorPagesIntro.Pages
@model IndexModel2

<h2>Separate page model</h2>
<p>
    @Model.Message
</p>

Pages/Index2.cshtml.cs sayfa modeli:

using Microsoft.AspNetCore.Mvc.RazorPages;
using System;

namespace RazorPagesIntro.Pages
{
    public class IndexModel2 : 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ı .cs ekli Razor Sayfa dosyası ile aynı adı içerir. Örneğin, önceki Sayfa Razor Pages/Index2.cshtml'dir. sınıfını içeren dosya PageModel Pages/Index2.cshtml.cs olarak adlandırılmıştır.

URL yollarının sayfalarla olan ilişkilendirmeleri, dosya sistemi içinde sayfanın konumu tarafından belirlenir. Aşağıdaki tabloda bir Sayfa yolu Razor ve eşleşen URL'si yer alır:

Dosya adı ve yolu 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ı varsayılan Razor olarak Sayfalar klasöründe Sayfalar dosyalarını aramaz.
  • Index , URL sayfa eklemezse varsayılan sayfadır.

Temel bir form yazma

Razor Sayfalar, web tarayıcıları ile kullanılan yaygın desenlerin uygulama oluştururken kolayca uygulanmasını sağlar. Model bağlama, Etiket Yardımcılarıve HTML yardımcılarının hepsi yalnızca Bir Sayfa sınıfında tanımlanan Razor özelliklerle çalışır. Model için temel bir "bize ulaşın" formunu uygulayan bir sayfa Contact düşünün:

Bu belgede yer alan örnekler DbContext için, Startup.cs dosyasında başlatılır.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using RazorPagesContacts.Data;

namespace RazorPagesContacts
{
    public class Startup
    {
        public IHostingEnvironment HostingEnvironment { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<AppDbContext>(options =>
                              options.UseInMemoryDatabase("name"));
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseMvc();
        }
    }
}

Veri modeli:

using System.ComponentModel.DataAnnotations;

namespace RazorPagesContacts.Data
{
    public class Customer
    {
        public int Id { get; set; }

        [Required, StringLength(100)]
        public string Name { get; set; }
    }
}

Veritabanı bağlamı:

using Microsoft.EntityFrameworkCore;

namespace RazorPagesContacts.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions options)
            : base(options)
        {
        }

        public DbSet<Customer> Customers { get; set; }
    }
}

Pages/Create.cshtml görünüm dosyası:

@page
@model RazorPagesContacts.Pages.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<html>
<body>
    <p>
        Enter your name.
    </p>
    <div asp-validation-summary="All"></div>
    <form method="POST">
        <div>Name: <input asp-for="Customer.Name" /></div>
        <input type="submit" />
    </form>
</body>
</html>

Pages/Create.cshtml.cs sayfa modeli:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesContacts.Data;

namespace RazorPagesContacts.Pages
{
    public class CreateModel : PageModel
    {
        private readonly AppDbContext _db;

        public CreateModel(AppDbContext db)
        {
            _db = db;
        }

        [BindProperty]
        public Customer Customer { get; set; }

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

            _db.Customers.Add(Customer);
            await _db.SaveChangesAsync();
            return RedirectToPage("/Index");
        }
    }
}

Kural gereği sınıfı PageModel <PageName>Model çağrılır ve sayfayla aynı ad alanı içindedir.

sınıfı, PageModel bir sayfanın mantığının sunumundan ayrılmasına olanak sağlar. Sayfaya gönderilen istekler için sayfa işleyicilerini ve sayfayı işlemek için kullanılan verileri tanımlar. Bu ayrım şunları sağlar:

Sayfada istekler OnPostAsync üzerinde çalışan bir işleyici POST yöntemi vardır (kullanıcı formu yayınlasa). Herhangi bir HTTP fiili için işleyici yöntemleri ekleyebilirsiniz. En yaygın işleyiciler şunlardır:

  • Sayfa için gereken durumu başlatmak için OnGet. OnGet örneği.
  • 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, Sayfalar için Razor tipiktir.

Denetleyiciler ve görünümler ASP.NET uygulamaları kullanma hakkında bilgi sahibiysiniz:

  • Yukarıdaki OnPostAsync örnekteki kod, tipik denetleyici koduna benzer şekilde görünüyor.
  • Model bağlama, doğrulama, Doğrulama ve eylem sonuçlarıgibi MVC temellerininçoğu paylaşılır.

Önceki OnPostAsync yöntem:

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

    _db.Customers.Add(Customer);
    await _db.SaveChangesAsync();
    return RedirectToPage("/Index");
}

temel OnPostAsync akışı:

Doğrulama hatalarını denetleyin.

  • Hata yoksa verileri kaydedin ve yeniden yönlendirmeyi kullanın.
  • Hatalar varsa doğrulama iletileriyle sayfayı yeniden gösterebilirsiniz. İstemci tarafı doğrulama, MVC uygulamalarıyla ASP.NET Core aynıdır. Çoğu durumda, doğrulama hataları istemci üzerinde algılanır ve sunucuya hiçbir zaman gönderilmez.

Veriler başarıyla girilirken, OnPostAsync işleyici yöntemi bir RedirectToPage örneğini dönmek için yardımcı yöntemini çağırmıştır. RedirectToPageResult RedirectToPage , veya gibi yeni bir eylem RedirectToAction sonucu, RedirectToRoute ancak sayfalar için özelleştirilmiştir. Yukarıdaki örnekte kök Dizin sayfasına () yeniden /Index yönlendirildi. RedirectToPage, Sayfalar için URL oluşturma bölümünde ayrıntılı olarak açıktır.

Gönderilen formda doğrulama hataları olduğunda (sunucuya geçirilenler), OnPostAsync işleyici yöntemi yardımcı Page yöntemini çağrıları. Page, bir PageResult örneği döndürür. Geri Page dönüş, denetleyicilerde eylemlerin döndürerek döndüren eylemlere View benzer. PageResult , bir işleyici yöntemi için varsayılan dönüş t t değeridir. Döndüren bir işleyici void yöntemi sayfayı işler.

özelliği, Customer model [BindProperty] bağlamayı kabul etmek için özniteliğini kullanır.

public class CreateModel : PageModel
{
    private readonly AppDbContext _db;

    public CreateModel(AppDbContext db)
    {
        _db = db;
    }

    [BindProperty]
    public Customer Customer { get; set; }

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

        _db.Customers.Add(Customer);
        await _db.SaveChangesAsync();
        return RedirectToPage("/Index");
    }
}

Razor Sayfalar varsayılan olarak özellikleri yalnızca fiil olmayanlarla GET bağlar. Özelliklere bağlamak, yazmanız gereken kod miktarını azaltabilir. Bağlama, form alanlarını ( ) işlemek ve girişi kabul etmek için <input asp-for="Customer.Name"> aynı özelliği kullanarak kodu azaltır.

Uyarı

Güvenlik nedeniyle, istek verilerini sayfa modeli GET özelliklerine bağlamayı kabul edebilirsiniz. Kullanıcı girişini özelliklere eşlemeden önce doğrulayın. Bağlamayı GET kabul etmek, sorgu dizesi veya yol değerlerine bağlı senaryoları ele almak için kullanışlıdır.

İsteklerde bir özelliği GET bağlamak için [BindProperty] özniteliğin özelliğini olarak SupportsGet true ayarlayın:

[BindProperty(SupportsGet = true)]

Daha fazla bilgi için bkz. ASP.NET Çekirdek Topluluk Standup: GET tartışmalarını bağlama (YouTube).

Giriş sayfası (Index.cshtml):

@page
@model RazorPagesContacts.Pages.IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<h1>Contacts</h1>
<form method="post">
    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var contact in Model.Customers)
            {
                <tr>
                    <td>@contact.Id</td>
                    <td>@contact.Name</td>
                    <td>
                        <a asp-page="./Edit" asp-route-id="@contact.Id">edit</a>
                        <button type="submit" asp-page-handler="delete" 
                                asp-route-id="@contact.Id">delete</button>
                    </td>
                </tr>
            }
        </tbody>
    </table>

    <a asp-page="./Create">Create</a>
</form>

İlişkili PageModel sınıfı (Index.cshtml.cs):

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesContacts.Data;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;

namespace RazorPagesContacts.Pages
{
    public class IndexModel : PageModel
    {
        private readonly AppDbContext _db;

        public IndexModel(AppDbContext db)
        {
            _db = db;
        }

        public IList<Customer> Customers { get; private set; }

        public async Task OnGetAsync()
        {
            Customers = await _db.Customers.AsNoTracking().ToListAsync();
        }

        public async Task<IActionResult> OnPostDeleteAsync(int id)
        {
            var contact = await _db.Customers.FindAsync(id);

            if (contact != null)
            {
                _db.Customers.Remove(contact);
                await _db.SaveChangesAsync();
            }

            return RedirectToPage();
        }
    }
}

Index.cshtml dosyası, her kişi için bir düzenleme bağlantısı oluşturmak için aşağıdaki işaretlemeyi içerir:

<a asp-page="./Edit" asp-route-id="@contact.Id">edit</a>

Yer <a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> Noktası Etiketi Yardımcısı, asp-route-{value} Düzenle sayfasının bağlantısını oluşturmak için özniteliğini kullandı. Bağlantı, kişi kimliğine sahip rota verilerini içerir. Örneğin, https://localhost:5001/Edit/1. Etiket Yardımcıları, sunucu tarafı kodunun dosyalarda HTML öğeleri oluşturma ve işlemeye katılmalarını Razor sağlar. Etiket Yardımcıları şu şekilde etkinleştirilir: @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Pages/Edit.cshtml dosyası:

@page "{id:int}"
@model RazorPagesContacts.Pages.EditModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

@{
    ViewData["Title"] = "Edit Customer";
}

<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 yönergesi @page "{id:int}" içerir. Yönlendirme "{id:int}" kısıtlaması, sayfaya yol verilerini içeren sayfaya yapılan istekleri kabul int etmelerini söyler. Sayfaya yapılan bir istek, bir 'a dönüştürülecek yol verileri int içeriyorsa, çalışma zamanı bir HTTP 404 (bulunamadı) hatası döndürür. Kimliği isteğe bağlı yapmak için yol ? kısıtlamasına ekleme:

@page "{id:int?}"

Pages/Edit.cshtml.cs dosyası:

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorPagesContacts.Data;

namespace RazorPagesContacts.Pages
{
    public class EditModel : PageModel
    {
        private readonly AppDbContext _db;

        public EditModel(AppDbContext db)
        {
            _db = db;
        }

        [BindProperty]
        public Customer Customer { get; set; }

        public async Task<IActionResult> OnGetAsync(int id)
        {
            Customer = await _db.Customers.FindAsync(id);

            if (Customer == null)
            {
                return RedirectToPage("/Index");
            }

            return Page();
        }

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

            _db.Attach(Customer).State = EntityState.Modified;

            try
            {
                await _db.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                throw new Exception($"Customer {Customer.Id} not found!");
            }

            return RedirectToPage("/Index");
        }
    }
}

Index.cshtml dosyası ayrıca her müşteri ilgili kişisi için bir silme düğmesi oluşturmak için işaretleme içerir:

<button type="submit" asp-page-handler="delete" 
        asp-route-id="@contact.Id">delete</button>

Sil düğmesi HTML'de işıldığında, formaction aşağıdakiler için parametreleri içerir:

  • Özniteliği tarafından belirtilen müşteri iletişim asp-route-id kimliği.
  • özniteliği handler tarafından asp-page-handler belirtilen.

Müşteri iletişim kimliğine sahip işlenmiş silme düğmesi örneği: 1

<button type="submit" formaction="/?id=1&amp;handler=delete">delete</button>

Düğme seçildiğinde sunucuya bir form POST isteği gönderilir. Kural gereği, işleyici yönteminin adı şemasına göre handler parametrenin değerine göre OnPost[handler]Async seçilir.

bu handler örnekte delete olduğundan, isteği OnPostDeleteAsync işlemek için işleyici yöntemi POST kullanılır. gibi asp-page-handler farklı bir değere remove ayarlanırsa, adıyla bir işleyici yöntemi OnPostRemoveAsync seçilir. Aşağıdaki kod işleyiciyi OnPostDeleteAsync gösterir:

public async Task<IActionResult> OnPostDeleteAsync(int id)
{
    var contact = await _db.Customers.FindAsync(id);

    if (contact != null)
    {
        _db.Customers.Remove(contact);
        await _db.SaveChangesAsync();
    }

    return RedirectToPage();
}

OnPostDeleteAsyncyöntemi:

  • Sorgu id dizesinden kabul eder. Index.cshtml sayfa yönergesi yönlendirme kısıtlaması "{id:int?}" içeriyorsa, yol id verilerinden gelir. için yol verileri id gibi URI'de https://localhost:5001/Customers/2 belirtilir.
  • ile müşteri iletişim kurmak için veritabanını FindAsync sorgular.
  • Müşteri ilgili kişisi bulunursa, müşteri kişi listesinden kaldırılır. Veritabanı güncelleştirilir.
  • Kök RedirectToPage Dizin sayfasına ( ) yeniden yönlendirmeye çağrılar. /Index

Sayfa özelliklerini gerekli olarak işaretleme

üzerinde özellikler PageModel Gerekli özniteliğiyle işaretlenir:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel.DataAnnotations;

namespace RazorPagesMovie.Pages.Movies
{
    public class CreateModel : PageModel
    {
        public IActionResult OnGet()
        {
            return Page();
        }

        [BindProperty]
        [Required(ErrorMessage = "Color is required")]
        public string Color { get; set; }

        public IActionResult OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            // Process color.

            return RedirectToPage("./Index");
        }
    }
}

Daha fazla bilgi için bkz. Model doğrulaması.

OnGet işleyicisi geri dönüş ile HEAD isteklerini işleme

HEAD istekleri, belirli bir kaynağın üst bilgilerini alasiniz. İsteklerin GET HEAD aksine, istekler bir yanıt gövdesi geri dönmez.

Normalde bir işleyici OnHead oluşturulur ve istekler için HEAD çağrılır:

public void OnHead()
{
    HttpContext.Response.Headers.Add("HandledBy", "Handled by OnHead!");
}

2 ASP.NET Core 2.1 veya sonraki bir sonraki bir yıl içinde, herhangi bir işleyici tanımlanmamışsa Razor Pages OnGet işleyiciyi OnHead çağırmaya geri döner. Bu davranış, içinde SetCompatibilityVersion çağrısıyla Startup.ConfigureServices etkinleştirilir:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

Varsayılan şablonlar çağrıyı SetCompatibilityVersion 2.1 ASP.NET Core 2.2'de oluşturur. SetCompatibilityVersion etkin bir şekilde Razor Sayfalar seçeneğini olarak AllowMappingHeadRequestsToGetHandler true ayarlar.

ile tüm davranışları kabul etmek SetCompatibilityVersion yerine, açıkça belirli davranışları kabulabilirsiniz. Aşağıdaki kod, isteklerin HEAD işleyiciyle eşlenmiş olması için izin vermeyi OnGet kabul ediyor:

services.AddMvc()
    .AddRazorPagesOptions(options =>
    {
        options.AllowMappingHeadRequestsToGetHandler = true;
    });

XSRF/CSRF ve Razor Sayfalar

Sahteciliği önleme doğrulaması için herhangi bir kod yazmanız gerek yok. Sahteciliği önleme belirteci oluşturma ve doğrulama, Sayfalar'a otomatik olarak Razor eklenir.

Sayfalarla Düzenleri, kısmileri, şablonları ve Etiket Yardımcılarını Razor Kullanma

Sayfalar, görünüm altyapısının tüm Razor özellikleriyle çalışır. Düzenler, kısmiler, şablonlar, Etiket Yardımcıları, _ViewStart.cshtml, _ViewImports.cshtml, geleneksel görünümlerde olduğu gibi Razor çalışır.

Bu özelliklerden bazılarına sahip olarak bu sayfayı biraz daha genişletebilirsiniz.

Pages/Shared/_Layout.cshtml'ye düzen sayfası ekleyin:

<!DOCTYPE html>
<html>
<head> 
    <title>Razor Pages Sample</title>      
</head>
<body>    
   <a asp-page="/Index">Home</a>
    @RenderBody()  
    <a asp-page="/Customers/Create">Create</a> <br />
</body>
</html>

Düzen:

  • Her sayfanın düzenini (sayfa düzeni devre dışı bırakmadıkça) kontrol eder.
  • JavaScript ve stil sayfaları gibi HTML yapılarını içeri aktarıyor.

Daha fazla bilgi için düzen sayfasına bakın.

Layout özelliği Pages/_ViewStart.cshtml içinde ayarlanır:

@{
    Layout = "_Layout";
}

Düzen Sayfalar/Paylaşılan klasöründedir. Sayfalar, geçerli sayfayla aynı klasörden başlayarak diğer görünümleri (düzenler, şablonlar, kısmi öğeler) hiyerarşik olarak aratır. Sayfalar/Paylaşılan klasöründeki bir düzen, Sayfalar klasörünün Razor altındaki herhangi bir sayfadan kullanılabilir.

Düzen dosyası Sayfalar/Paylaşılan klasörüne iner.

Düzen dosyasını Görünümler/Paylaşılan klasörüne koymamanız önerilir. Görünümler/Paylaşılan bir MVC görünüm desenidir. Razor Sayfalar, yol kurallarına değil klasör hiyerarşisini dayandırarak kullanılır.

Sayfalar klasörünü içeren Razor bir Sayfadan arama görüntüleme. MVC denetleyicileri ve geleneksel görünümlerle birlikte kullanmakta olduğunu düzenleri, şablonları ve kısmileri Razor yalnızca çalışır.

Pages/_ViewImports.cshtml dosyası ekleyin:

@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

@namespace öğreticinin sonraki adımlarında açıklanmıştır. @addTagHelperyönergesi yerleşik Etiket Yardımcılarını Sayfalar klasöründeki tüm sayfalara getirir.

Yönerge @namespace bir sayfada açıkça kullanılırken:

@page
@namespace RazorPagesIntro.Pages.Customers

@model NameSpaceModel

<h2>Name space</h2>
<p>
    @Model.Message
</p>

yönergesi, sayfa için ad alanını ayarlar. yönergesi @model ad alanını içermesine gerek yok.

yönergesi @namespace _ViewImports.cshtml içinde olduğunda, belirtilen ad alanı yönergeyi içeri aktaran Sayfada oluşturulan ad alanı için ön eki @namespace sağlar. Oluşturulan ad alanının geri kalanı (sonek bölümü), _ViewImports.cshtml dosyasını içeren klasör ile sayfayı içeren klasör arasındaki noktayla ayrılmış göreli yoldur.

Örneğin, PageModel Pages/Customers/Edit.cshtml.cs sınıfı ad alanını açıkça ayarlar:

namespace RazorPagesContacts.Pages
{
    public class EditModel : PageModel
    {
        private readonly AppDbContext _db;

        public EditModel(AppDbContext db)
        {
            _db = db;
        }

        // Code removed for brevity.

Pages/_ViewImports.cshtml dosyası aşağıdaki ad alanını ayarlar:

@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Pages/Customers/Edit.cshtml Sayfası için oluşturulan ad Razor alanı sınıfıyla PageModel aynıdır.

@namespacegeleneksel görünümlerle de Razor çalışır.

Özgün Pages/Create.cshtml görünüm dosyası:

@page
@model RazorPagesContacts.Pages.CreateModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<html>
<body>
    <p>
        Enter your name.
    </p>
    <div asp-validation-summary="All"></div>
    <form method="POST">
        <div>Name: <input asp-for="Customer.Name" /></div>
        <input type="submit" />
    </form>
</body>
</html>

Güncelleştirilmiş Pages/Create.cshtml görünüm dosyası:

@page
@model CreateModel

<html>
<body>
    <p>
        Enter your name.
    </p>
    <div asp-validation-summary="All"></div>
    <form method="POST">
        <div>Name: <input asp-for="Customer.Name" /></div>
        <input type="submit" />
    </form>
</body>
</html>

Sayfalar Razor başlangıç projesi, istemci tarafı doğrulamayı _ValidationScriptsPartial Pages/_ValidationScriptsPartial.cshtml dosyasını içerir.

Kısmi görünümler hakkında daha fazla bilgi için ASP.NET Core'de kısmi görünümler bkz. .

Sayfalar için URL oluşturma

Daha Create önce gösterilen sayfa RedirectToPage kullanır:

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

    _db.Customers.Add(Customer);
    await _db.SaveChangesAsync();
    return RedirectToPage("/Index");
}

Uygulama aşağıdaki dosya/klasör yapısına sahiptir:

  • /Pages

    • Index.cshtml

    • /Customers

      • Create.cshtml
      • Edit.cshtml
      • Index.cshtml

Pages/Customers/Create.cshtml ve Pages/Customers/Edit.cshtml sayfaları başarıdan sonra Pages/Index.cshtml sayfasına yeniden yönlendirmektedir. Dize, /Index önceki sayfaya erişmek için URI'nin bir parçası. Dize, /Index Pages/Index.cshtml sayfasına URL oluşturmak için kullanılabilir. Örnek:

  • Url.Page("/Index", ...)
  • <a asp-page="/Index">My Index Page</a>
  • RedirectToPage("/Index")

Sayfa adı, kök /Pages klasöründen bir baştaki (örneğin, ) sayfanın / /Index yoludur. Önceki URL oluşturma örnekleri, BIR URL'yi sabit kodlama üzerinde gelişmiş seçenekler ve işlevsel özellikler sunar. URL oluşturma yönlendirmeyi kullanır ve yolun hedef yolda nasıl tanımlandığına göre parametreler üretin ve kodlayabilir.

Sayfalar için URL oluşturma, göreli adları destekler. Aşağıdaki tabloda RedirectToPage Pages/Customers/Create.cshtml parametresinden farklı parametrelerle hangi Dizin sayfasının seçilecekleri listelemektedir:

RedirectToPage(x) Sayfa
RedirectToPage("/Index") Sayfalar/Dizin
RedirectToPage("./Index"); Sayfalar/Müşteriler/Dizin
RedirectToPage(".. /Index") Sayfalar/Dizin
RedirectToPage("Index") Sayfalar/Müşteriler/Dizin

RedirectToPage("Index"), RedirectToPage("./Index") ve RedirectToPage("../Index") göreli adlarıdır. RedirectToPageparametresi, hedef sayfanın adını hesaplamak için geçerli sayfanın yoluyla birleştirilmiştir.

Göreli ad bağlama, karmaşık bir yapıya sahip siteler inşası için kullanışlıdır. Bir klasördeki sayfalar arasında bağlantı için göreli adlar kullanırsanız, bu klasörü yeniden adlandırabilirsiniz. Tüm bağlantılar çalışmaya devam ediyor (klasör adını içermedi).

Farklı bir Alanda bir sayfaya yeniden yönlendirmek içinalanı belirtin:

RedirectToPage("/Index", new { area = "Services" });

Daha fazla bilgi için bkz. ASP.NET Core bölgeler.

ViewData özniteliği

Veriler ViewDataAttribute ile bir sayfaya geçirebilirsiniz. Denetleyiciler veya Razor öznitelikli Sayfa [ViewData] modellerinin özellikleri, değerlerinin ViewDataDictionaryiçinde depolanmış ve yüklenmiştir.

Aşağıdaki örnekte, ile AboutModel işaretlenmiş bir özellik Title [ViewData] içerir. özelliği Title Hakkında sayfasının başlığına ayarlanır:

public class AboutModel : PageModel
{
    [ViewData]
    public string Title { get; } = "About";

    public void OnGet()
    {
    }
}

Hakkında sayfasında, özelliğine Title model özelliği olarak erişin:

<h1>@Model.Title</h1>

Düzende başlık ViewData sözlüğünden okunur:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>@ViewData["Title"] - WebApplication</title>
    ...

TempData

ASP.NET Core bir denetleyicide TempData özelliğini gösterir. Bu özellik, okunana kadar verileri depolar. ve Keep Peek yöntemleri, verileri silinmeden incelemek için kullanılabilir. TempData , tek bir istekten daha fazla veri gerektiğinde yeniden yönlendirme için kullanışlıdır.

Aşağıdaki kod, değerini kullanarak Message TempData 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ındaki aşağıdaki işaretleme, kullanarak değerini Message TempData görüntüler.

<h3>Msg: @Model.Message</h3>

Pages/Customers/Index.cshtml.cs sayfa modeli [TempData] özniteliğini özelliğine Message uygular.

[TempData]
public string Message { get; set; }

Daha fazla bilgi için bkz. TempData .

Sayfa başına birden çok işleyici

Aşağıdaki sayfada Etiket Yardımcısı kullanılarak iki işleyici için asp-page-handler işaretleme oluşturulur:

@page
@model CreateFATHModel

<html>
<body>
    <p>
        Enter your name.
    </p>
    <div asp-validation-summary="All"></div>
    <form method="POST">
        <div>Name: <input asp-for="Customer.Name" /></div>
        <input type="submit" asp-page-handler="JoinList" value="Join" />
        <input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
    </form>
</body>
</html>

Önceki örnekteki formda, her biri farklı bir URL'ye göndermek için kullanan FormActionTagHelper iki gönderme düğmesi vardır. özniteliği, asp-page-handler için bir asp-page yardımcıdır. asp-page-handler , bir sayfa tarafından tanımlanan her bir işleyici yöntemine gönderme URL'leri üretir. asp-page belirtilmez çünkü örnek geçerli sayfaya bağlantı sağlar.

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öntemlerini kullanır. Adlandırılmış işleyici yöntemleri, adından sonra ve (varsa) önce metni On<HTTP Verb> alarak Async oluşturulur. Yukarıdaki örnekte, sayfa yöntemleri OnPost JoinList Async ve OnPost JoinListUC Async'tir. OnPost ve Async kaldırılarak işleyici adları ve JoinList JoinListUC olur.

<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />

Önceki kodu kullanarak, adresine gönderilen URL yolu OnPostJoinListAsync https://localhost:5001/Customers/CreateFATH?handler=JoinList olur. adresine gönderilen URL OnPostJoinListUCAsync https://localhost:5001/Customers/CreateFATH?handler=JoinListUC yoludur.

Özel yollar

Yönergeyi @page kullanarak şunları yapmak için:

  • Sayfaya özel bir yol belirtin. Örneğin Hakkında sayfasına giden yol ile olarak ayarlanmış /Some/Other/Path @page "/Some/Other/Path" olabilir.
  • Segmentleri sayfanın varsayılan yolunun sonuna ekleyin. Örneğin, bir "öğe" segmenti ile sayfanın varsayılan yoluna @page "item" eklenebilir.
  • Parametreleri sayfanın varsayılan yolunun sonuna ekleyin. Örneğin, kimlik parametresi, id ile bir sayfa için gerekli @page "{id}" olabilir.

Yolun başındaki bir tilde ( ) tarafından belirlenen kök göreli ~ yol de desteklenmeli. Örneğin, @page "~/Some/Other/Path" ile @page "/Some/Other/Path" aynıdır.

URL'de sorgu dizesini tercih ediyorsanız, işleyici adını URL'nin yol bölümüne ?handler=JoinList koymak için yolu değiştirebilirsiniz. Yönergeden sonra çift tırnak içine alınmış bir yol şablonu ekilerek yol @page özelleştirilebilir.

@page "{handler?}"
@model CreateRouteModel

<html>
<body>
    <p>
        Enter your name.
    </p>
    <div asp-validation-summary="All"></div>
    <form method="POST">
        <div>Name: <input asp-for="Customer.Name" /></div>
        <input type="submit" asp-page-handler="JoinList" value="Join" />
        <input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
    </form>
</body>
</html>

Önceki kodu kullanarak, adresine gönderilen URL yolu OnPostJoinListAsync https://localhost:5001/Customers/CreateFATH/JoinList olur. adresine gönderilen URL OnPostJoinListUCAsync https://localhost:5001/Customers/CreateFATH/JoinListUC yoludur.

Aşağıdaki, ? handler yol parametresinin isteğe bağlı olduğu anlamına gelir.

Yapılandırma ve ayarlar

Gelişmiş seçenekleri yapılandırmak için AddRazorPagesOptions MVC oluşturucusu üzerinde uzantı yöntemini kullanın:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddRazorPagesOptions(options =>
        {
            options.RootDirectory = "/MyPages";
            options.Conventions.AuthorizeFolder("/MyPages/Admin");
        });
}

Şu anda sayfaların kök dizinini ayarlamak veya sayfalar için uygulama modeli kuralları RazorPagesOptions eklemek için kullanabilirsiniz. Gelecekte bu şekilde daha fazla genişletilebilirliği etkinleştireceğiz.

Görünümleri önceden derlemek için bkz. Razor derlemeyi görüntüleme.

Örnek kodu indirin veya görüntün.

Bu Kullanmaya başlayın Razor temel alanPages ile ilgili genel girişlere bakın.

Sayfaların Razor içerik kökünde olduğunu belirtme

Varsayılan olarak, Razor Sayfalar'ın kökü /Pages dizinindedir. Sayfalarınızı uygulamanın içerik kökünde ( ContentRootPath ) belirtmek için AddMvc'ye Razor PagesAtContentRoot Razor ile Ekleyin:

services.AddMvc()
    .AddRazorPagesOptions(options =>
    {
        ...
    })
    .WithRazorPagesAtContentRoot();

Sayfaların Razor özel bir kök dizinde olduğunu belirtme

Sayfalarınızı uygulamada özel bir kök dizinde olduğunu belirtmek için AddMvc'ye Razor PagesRoot ile Ekle Razor (göreli bir yol belirtin):

services.AddMvc()
    .AddRazorPagesOptions(options =>
    {
        ...
    })
    .WithRazorPagesRoot("/path/to/razor/pages");

Ek kaynaklar