Úvod do Razor Pages v ASP.NET Core
Autoři: Rick Anderson, Dave Brock a Kirk Larkin
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Model Razor Pages může usnadnit a zefektivnit kódování scénářů zaměřených na stránky oproti používání kontrolerů a zobrazení.
Pokud hledáte kurz zaměřený na model MVC (Model-View-Controller), projděte si téma Začínáme s ASP.NET Core MVC.
Tento dokument poskytuje úvod k Razor Pages. Nejedná se o podrobný kurz. Pokud zjistíte, že jsou pro vás některé části příliš pokročilé, projděte si téma Začínáme s Razor Pages. Přehled ASP.NET Core najdete v tématu Úvod do ASP.NET Core.
Požadavky
- Sada Visual Studio 2022 se sadou funkcí Vývoj pro ASP.NET a web
- Sada .NET 6.0 SDK
Vytvoření projektu Razor Pages
Podrobné pokyny k vytvoření projektu Razor Pages najdete v tématu Začínáme s Razor Pages.
Razor Pages
Razor Pages se povoluje v souboru Program.cs
:
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();
V předchozím kódu:
- Metoda AddRazorPages do aplikace přidá služby pro Razor Pages.
- Metoda MapRazorPages do rozhraní IEndpointRouteBuilder přidá koncové body pro Razor Pages.
Podívejte se například na základní stránku:
@page
<h1>Hello, world!</h1>
<h2>The time on the server is @DateTime.Now</h2>
Výše uvedený kód se velmi podobá souboru zobrazení Razor, který se používá v aplikacích ASP.NET Core s kontrolery a zobrazeními. Liší se v direktivě @page
. Direktiva @page
ze souboru udělá akci MVC, což znamená, že bude zpracovávat požadavky přímo, aniž by procházely kontrolerem. Direktiva @page
musí být první direktivou Razor na stránce. Direktiva @page
ovlivňuje chování dalších konstrukcí Razor. Názvy souborů Razor Pages mají příponu .cshtml
.
V následujících dvou souborech je ukázka podobné stránky s použitím třídy PageModel
. Soubor Pages/Index2.cshtml
:
@page
@using RazorPagesIntro.Pages
@model Index2Model
<h2>Separate page model</h2>
<p>
@Model.Message
</p>
Model stránky Pages/Index2.cshtml.cs
:
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 }";
}
}
}
Podle konvence má soubor třídy PageModel
stejný název jako soubor stránky Razor s příponou .cs
. Například výše uvedená stránka Razor se nachází v souboru Pages/Index2.cshtml
. Soubor obsahující třídu PageModel
má název Pages/Index2.cshtml.cs
.
Přidružení cest URL ke stránkám se určuje podle umístění stránky v systému souborů. Následující tabulka ukazuje cestu ke stránce Razor a odpovídající adresu URL:
Název souboru a cesta | Odpovídající adresa URL |
---|---|
/Pages/Index.cshtml |
/ nebo /Index |
/Pages/Contact.cshtml |
/Contact |
/Pages/Store/Contact.cshtml |
/Store/Contact |
/Pages/Store/Index.cshtml |
/Store nebo /Store/Index |
Poznámky:
- Modul runtime ve výchozím nastavení hledá soubory Razor Pages ve složce Pages.
- Pokud adresa URL neobsahuje žádnou stránku, výchozí stránka je
Index
.
Napsání základního formuláře
Model Razor Pages je navržený tak, aby při vytváření aplikace usnadňoval implementaci běžných modelů používaných ve webových prohlížečích. Vazba modelu, pomocné rutiny značek a pomocné rutiny HTML fungují s vlastnostmi definovanými v třídě stránky Razor. Podívejte se například na stránku, která pro model Contact
implementuje základní kontaktní formulář:
U ukázek v tomto dokumentu DbContext
se inicializuje v souboru Program.cs .
Databáze v paměti vyžaduje balíček NuGet Microsoft.EntityFrameworkCore.InMemory
.
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();
Datový model:
using System.ComponentModel.DataAnnotations;
namespace RazorPagesContacts.Models
{
public class Customer
{
public int Id { get; set; }
[Required, StringLength(10)]
public string? Name { get; set; }
}
}
Kontext databáze:
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>();
}
}
Soubor zobrazení Pages/Customers/Create.cshtml
:
@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>
Model stránky Pages/Customers/Create.cshtml.cs
:
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");
}
}
Podle konvence má třída PageModel
název <PageName>Model
a nachází se ve stejném oboru názvů jako stránka.
Třída PageModel
umožňuje oddělit logiku stránky od její prezentace. Definuje obslužné rutiny stránky pro požadavky odeslané na stránku a pro data použitá k vykreslení stránky. Toto oddělení umožňuje:
- Správu závislostí stránky prostřednictvím injektáže závislostí
- Testování jednotek
Stránka má metodu obslužné OnPostAsync
rutiny, která se spouští na POST
žádostech (když uživatel publikuje formulář). Je možné přidat metody obslužných událostí pro jakékoli příkazy HTTP. Nejběžnější obslužné rutiny jsou:
OnGet
pro inicializaci stavu potřebného pro stránku. Ve výše uvedeném kódu metodaOnGet
zobrazí stránku RazorCreate.cshtml
.OnPost
pro zpracování odesílání formulářů.
Přípona názvu Async
je volitelná, ale často se podle konvence používá pro asynchronní funkce. Výše uvedený kód je pro Razor Pages typický.
Pokud máte zkušenosti s aplikacemi ASP.NET využívajícími kontrolery a zobrazení:
- Kód metody
OnPostAsync
ve výše uvedeném příkladu se podobá typickému kódu kontroleru. - Většina primitiv MVC, jako jsou vazba modelu, ověřování a výsledky akcí, funguje v Razor Pages stejně jako u kontrolerů.
Výše uvedená metoda OnPostAsync
:
[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");
}
Základní tok metody OnPostAsync
:
Zkontroluje, jestli nedošlo k chybám ověřování.
- Pokud nedošlo k žádným chybám, uloží data a provede přesměrování.
- Pokud došlo k chybám, znovu zobrazí stránku s ověřovacími zprávami. V mnoha případech by se v klientovi zjistily chyby ověřování a nikdy by se neodeslaly na server.
Soubor zobrazení Pages/Customers/Create.cshtml
:
@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>
Vykreslený kód HTML ze souboru Pages/Customers/Create.cshtml
:
<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>
Ve výše uvedeném kódu se po odeslání formuláře stane následující:
V případě platných dat:
Metoda obslužné rutiny
OnPostAsync
zavolá metodu obslužné rutiny RedirectToPage.RedirectToPage
vrací instanci RedirectToPageResult.RedirectToPage
:- Je výsledek akce.
- Je metoda podobná metodám
RedirectToAction
neboRedirectToRoute
(které se používají v kontrolerech a zobrazeních). - Je metoda přizpůsobená pro stránky. Ve výše uvedené ukázce provádí přesměrování na kořenovou indexovou stránku (
/Index
). MetodaRedirectToPage
je podrobně popsaná v části Generování adres URL pro stránky.
V případě chyb ověřování předaných na server:
- Metoda obslužné rutiny
OnPostAsync
zavolá metodu obslužné rutiny Page.Page
vrací instanci PageResult. Vrácení objektuPage
se podobá tomu, jak akce v kontrolerech vrací objektView
. Výchozí návratový typ metody obslužné rutiny jePageResult
. Metoda obslužné rutiny, která vrátí hodnotuvoid
, vykreslí stránku. - Ve výše uvedeném příkladu odeslání formuláře bez jakékoli hodnoty způsobí, že ModelState.IsValid vrátí hodnotu false. V této ukázce se v klientovi nezobrazí žádné chyby ověřování. Zpracování chyb ověřování se věnujeme dále v tomto dokumentu.
[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"); }
- Metoda obslužné rutiny
V případě detekce chyb ověřování při ověřování na straně klienta:
- Data se neodešlou na server.
- Ověřování na straně klienta se věnujeme dále v tomto dokumentu.
Vlastnost Customer
pro přihlášení k vazbě modelu používá atribut [BindProperty]
:
[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");
}
Atribut [BindProperty]
by se neměl používat u modelů obsahujících vlastnosti, které by klient neměl měnit. Další informace najdete v části Útoky typu overpost.
Razor Pages ve výchozím nastavení váže vlastnosti pouze k jiným příkazům než GET
. Díky vazbě na vlastnosti odpadá nutnost psát kód pro převod dat HTTP na typ modelu. Vazba snižuje množství kódu díky tomu, že se k vykreslení polí formuláře (<input asp-for="Customer.Name">
) a příjmu vstupu používá stejná vlastnost.
Upozorňující
Z bezpečnostních důvodů musíte vyjádřit souhlas s vazbou dat požadavků GET
na vlastnosti modelu stránky. Před mapováním uživatelského vstupu na vlastnosti tento vstup ověřte. Vyjádření souhlasu s vazbou požadavků GET
je užitečné při řešení scénářů, které se spoléhají na řetězec dotazu nebo hodnoty trasy.
Pokud chcete vytvořit vazbu vlastnosti na požadavky GET
, nastavte vlastnost SupportsGet
atributu [BindProperty]
na hodnotu true
:
[BindProperty(SupportsGet = true)]
Další informace najdete ve videu Přehled novinek v komunitě ASP.NET Core: Diskuze k vazbě požadavků GET (YouTube).
Projděte si soubor zobrazení Pages/Customers/Create.cshtml
:
@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>
- V předchozím kódu pomocné rutina
<input asp-for="Customer.Name" />
vstupní značky sváže element HTML<input>
s výrazemCustomer.Name
modelu. - Direktiva
@addTagHelper
zpřístupňuje pomocné rutiny značek.
Stránka home
Index.cshtml
home je stránka:
@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>
Přidružená třída PageModel
(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();
}
}
Soubor Index.cshtml
obsahuje následující kód:
<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |
Pomocná rutina <a /a>
značky ukotvení použila asp-route-{value}
atribut k vygenerování odkazu na stránku Upravit. Odkaz obsahuje data trasy a ID kontaktu. Například https://localhost:5001/Edit/1
. Pomocné rutiny značek umožňují, aby se kód na straně serveru v souborech Razor podílel na vytváření a vykreslování elementů HTML.
Soubor Index.cshtml
obsahuje kód, který pro každý kontakt zákazníka vytvoří tlačítko pro odstranění:
<button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button>
Vykreslený kód HTML:
<button type="submit" formaction="/Customers?id=1&handler=delete">delete</button>
Když se tlačítko pro odstranění vykreslí v HTML, jeho atribut formaction obsahuje parametry pro:
- ID kontaktu zákazníka zadané atributem
asp-route-id
- Obslužnou rutinu
handler
zadanou atributemasp-page-handler
Při výběru tohoto tlačítka se na server odešle požadavek POST
formuláře. Podle konvence se název metody obslužné rutiny vybírá na základě hodnoty parametru handler
ve schématu OnPost[handler]Async
.
Vzhledem k tomu, že parametr handler
má v tomto příkladu hodnotu delete
, ke zpracování požadavku POST
se použije metoda obslužné rutiny OnPostDeleteAsync
. Pokud je atribut asp-page-handler
nastavený na jinou hodnotu, například remove
, vybere se metoda obslužné rutiny s názvem OnPostRemoveAsync
.
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();
}
Metoda OnPostDeleteAsync
:
- Získá z řetězce dotazu hodnotu
id
. - Pomocí metody
FindAsync
odešle do databáze dotaz na kontakt zákazníka. - Pokud se kontakt zákazníka najde, odebere se a databáze se aktualizuje.
- Zavolá metodu RedirectToPage, která provede přesměrování na kořenovou indexovou stránku (
/Index
).
Soubor Edit.cshtml
@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");}
}
První řádek obsahuje direktivu @page "{id:int}"
. Omezení směrování "{id:int}"
stránce říká, že má přijímat požadavky na stránku, které obsahují data trasy typu int
. Pokud požadavek na stránku neobsahuje data trasy, která je možné převést na hodnotu typu int
, modul runtime vrátí chybu HTTP 404 (Nenalezeno). Pokud chcete nastavit ID jako volitelné, připojte k omezení trasy symbol ?
:
@page "{id:int?}"
Soubor Edit.cshtml.cs
:
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);
}
}
Ověřování
Pravidla ověřování:
- Zadávají se deklarativně v třídě modelu.
- Vynucují se v rámci celé aplikace.
Obor názvů System.ComponentModel.DataAnnotations nabízí sadu předdefinovaných atributů ověřování, které je možné deklarativně použít na třídu nebo vlastnost. Obor názvů DataAnnotations obsahuje také atributy formátování, jako je [DataType]
, které pomáhají s formátováním a neposkytují žádné ověřování.
Podívejte se například na model Customer
:
using System.ComponentModel.DataAnnotations;
namespace RazorPagesContacts.Models
{
public class Customer
{
public int Id { get; set; }
[Required, StringLength(10)]
public string? Name { get; set; }
}
}
Používá se následující soubor zobrazení Create.cshtml
:
@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>
Předchozí kód:
Vkládá knihovnu jQuery a ověřovací skripty jQuery.
Pomocí pomocných rutin a
<span />
pomocných<div />
rutin značek povolíte:- Ověřování na straně klienta
- Vykreslování chyb ověřování
Generuje následující kód 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> <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>
Při odeslání formuláře pro vytvoření bez hodnoty názvu se ve formuláři zobrazí chybová zpráva Pole Name je povinné. Pokud je v klientovi povolený JavaScript, v prohlížeči se zobrazí chyba, aniž by se formulář odeslal na server.
Atribut [StringLength(10)]
ve vykresleném kódu HTML vygeneruje atribut data-val-length-max="10"
. Atribut data-val-length-max
brání v prohlížečích v zadání více znaků, než je zadaná maximální délka. Pokud se k úpravě a opětovnému odeslání použije nástroj typu Fiddler:
- Pokud je název delší než 10 znaků:
- Vrátí se chybová zpráva Pole Name musí obsahovat řetězec o maximální délce 10 znaků.
Podívejte se například na následující model 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; }
}
}
Atributy ověřování určují chování, které se má vynucovat u vlastností modelu, na které se použijí:
Atributy
Required
aMinimumLength
značí, že vlastnost musí mít nějakou hodnotu, ale uživateli nic nebrání v zadání prázdných znaků, které tímto ověřením projdou.Atribut
RegularExpression
slouží k omezení množiny znaků, které je možné zadat. Pro vlastnost Genre ve výše uvedeném kódu platí následující:- Může obsahovat pouze písmena.
- Počáteční písmeno musí být velké. Nemůže obsahovat prázdné znaky, číslice ani speciální znaky.
Regulární výraz (
RegularExpression
) u vlastnosti Rating:- Vyžaduje, aby prvním znakem bylo velké písmeno.
- Na dalších místech povoluje speciální znaky a číslice. PG-13 je platná hodnota pro vlastnost Rating, ale ne pro vlastnost Genre.
Atribut
Range
omezuje hodnotu v konkrétním rozsahu.Atribut
StringLength
nastavuje maximální délku řetězcové vlastnosti a volitelně i její minimální délku.Typy hodnot (například
decimal
,int
,float
,DateTime
) jsou ze své podstaty povinné a nevyžadují atribut[Required]
.
Na stránce pro vytvoření pro model Movie
se v případě neplatných hodnot zobrazí chyby:
Další informace naleznete v tématu:
Izolace šablon stylů CSS
Izolujte styly CSS na jednotlivé stránky, zobrazení a komponenty, abyste omezili nebo eliminovali:
- Závislosti na globálních stylech, jejichž údržba může být náročná
- Konflikty stylů ve vnořeném obsahu
Pokud chcete pro stránku nebo zobrazení přidat soubor CSS s vymezeným oborem, umístěte styly CSS do doprovodného souboru .cshtml.css
se stejným názvem jako soubor .cshtml
. V následujícím příkladu soubor Index.cshtml.css
obsahuje styly CSS, které se použijí pouze pro stránku nebo zobrazení Index.cshtml
.
Pages/Index.cshtml.css
(Razor Pages) nebo Views/Index.cshtml.css
(MVC):
h1 {
color: red;
}
K izolaci šablon stylů CSS dochází v okamžiku sestavení. Architektura přepíše selektory CSS tak, aby odpovídaly kódu vykreslenému stránkami nebo zobrazeními aplikace. Přepsané styly CSS se sdruží do statického prostředku {APP ASSEMBLY}.styles.css
. Zástupný symbol {APP ASSEMBLY}
je název sestavení projektu. Do rozložení aplikace se umístí odkaz na sdružené styly CSS.
Ověřte, že element <head>
v souboru Pages/Shared/_Layout.cshtml
(Razor Pages) nebo Views/Shared/_Layout.cshtml
(MVC) aplikace obsahuje odkaz na sdružené styly CSS, případně tento odkaz přidejte:
<link rel="stylesheet" href="~/{APP ASSEMBLY}.styles.css" />
V následujícím příkladu je název sestavení aplikace WebApp
:
<link rel="stylesheet" href="WebApp.styles.css" />
Styly definované v souboru CSS s vymezeným oborem se použijí pouze pro vykreslený výstup odpovídajícího souboru. Ve výše uvedeném příkladu nejsou žádné deklarace CSS elementu h1
definované v jiných částech aplikace v konfliktu se stylem nadpisu pro Index
. Pro soubory CSS s vymezeným oborem stále platí pravidla kaskádování a dědičnosti stylů CSS. Například styly použité přímo pro element <h1>
v souboru Index.cshtml
přepíší styly v souboru CSS s vymezeným oborem Index.cshtml.css
.
Poznámka:
V zájmu zajištění izolace stylů CSS při sdružování se nepodporuje import šablon stylů CSS v blocích kódu Razor.
Izolace šablon stylů CSS se vztahuje pouze na elementy HTML. Izolace šablon stylů pro pomocné rutiny značek se nepodporuje.
V rámci sdruženého souboru CSS je ke každé stránce, každému zobrazení a každé komponentě Razor přidružený identifikátor oboru ve formátu b-{STRING}
, kde zástupný symbol {STRING}
je řetězec 10 znaků vygenerovaný architekturou. Následující příklad ukazuje styl pro výše uvedený element <h1>
na stránce Index
aplikace Razor Pages:
/* /Pages/Index.cshtml.rz.scp.css */
h1[b-3xxtam6d07] {
color: red;
}
Na stránce Index
, na které se použije tento styl CSS ze sdruženého souboru, se identifikátor oboru připojí jako atribut HTML:
<h1 b-3xxtam6d07>
Identifikátor je pro každou aplikaci jedinečný. V okamžiku sestavení se vytvoří sada prostředků projektu s použitím konvence {STATIC WEB ASSETS BASE PATH}/Project.lib.scp.css
, kde zástupný symbol {STATIC WEB ASSETS BASE PATH}
je základní cesta ke statickým webovým prostředkům.
Pokud se využívají jiné projekty, jako jsou balíčky NuGet nebo knihovny tříd Razor, sdružený soubor:
- Odkazuje na styly pomocí importu šablon stylů CSS.
- Není publikovaný jako statický webový prostředek aplikace, která styly využívá.
Podpora preprocesorů CSS
Preprocesory CSS jsou užitečné pro zlepšení vývoje šablon stylů CSS díky tomu, že umožňují využívat funkce, jako jsou proměnné, vnořování, moduly, mixiny nebo dědičnost. I když izolace šablon stylů CSS nativně nepodporuje preprocesory CSS, jako jsou Sass nebo Less, integrace preprocesorů CSS je bezproblémová, pokud ke kompilaci preprocesoru dochází před tím, než architektura během procesu sestavení přepíše selektory CSS. Pokud například používáte sadu Visual Studio, v Průzkumníku spouštěče úloh sady Visual Studio nakonfigurujte kompilaci stávajícího preprocesoru jako úlohu Před sestavením.
Řada balíčků NuGet třetích stran, jako je AspNetCore.SassCompiler
, dokáže bez nutnosti další konfigurace kompilovat soubory SASS/SCSS na začátku procesu sestavení, než dojde k izolaci šablon stylů CSS.
Konfigurace izolace šablon stylů CSS
Izolace šablon stylů CSS umožňuje konfiguraci pro některé pokročilé scénáře, například když existují závislosti na stávajících nástrojích nebo pracovních postupech.
Úprava formátu identifikátoru oboru
Zástupný symbol {Pages|Views}
v této části má hodnotu Pages
v případě aplikací Razor Pages, nebo Views
v případě aplikací MVC.
Ve výchozím nastavení jsou identifikátory oboru ve formátu b-{STRING}
, kde zástupný symbol {STRING}
je řetězec 10 znaků vygenerovaný architekturou. Pokud chcete formát identifikátoru oboru upravit, aktualizujte soubor projektu s použitím požadovaného vzoru:
<ItemGroup>
<None Update="{Pages|Views}/Index.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Ve výše uvedeném příkladu se v šablonách stylů CSS vygenerovaných pro soubor Index.cshtml.css
změní identifikátor oboru z formátu b-{STRING}
na custom-scope-identifier
.
Pomocí identifikátorů oboru můžete dosáhnout dědičnosti u souborů CSS s vymezeným oborem. V následujícím příkladu souboru projektu soubor BaseView.cshtml.css
obsahuje společné styly pro všechna zobrazení. Soubor DerivedView.cshtml.css
tyto styly dědí.
<ItemGroup>
<None Update="{Pages|Views}/BaseView.cshtml.css" CssScope="custom-scope-identifier" />
<None Update="{Pages|Views}/DerivedView.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Pokud chcete sdílet identifikátory oboru mezi několika soubory, použijte operátor zástupného znaku (*
):
<ItemGroup>
<None Update="{Pages|Views}/*.cshtml.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Změna základní cesty ke statickým webovým prostředkům
Soubor CSS s vymezeným oborem se vygeneruje v kořenovém adresáři aplikace. Výchozí cestu můžete změnit pomocí vlastnosti StaticWebAssetBasePath
v souboru projektu. Následující příklad umístí soubor CSS s vymezeným oborem a rest prostředky aplikace na _content
cestu:
<PropertyGroup>
<StaticWebAssetBasePath>_content/$(PackageId)</StaticWebAssetBasePath>
</PropertyGroup>
Zakázání automatického sdružování
Pokud chcete vyjádřit výslovný nesouhlas s tím, jak architektura publikuje a načítá soubory s vymezeným oborem za běhu, použijte vlastnost DisableScopedCssBundling
. Pokud použijete tuto vlastnost, za přebírání izolovaných souborů CSS z adresáře obj
a jejich publikování a načítání za běhu budou zodpovídat jiné nástroje nebo procesy:
<PropertyGroup>
<DisableScopedCssBundling>true</DisableScopedCssBundling>
</PropertyGroup>
Podpora knihovny tříd Razor (RCL)
Pokud knihovna tříd Razor (RCL) nabízí izolované styly, atribut href
značky <link>
odkazuje na soubor {STATIC WEB ASSET BASE PATH}/{PACKAGE ID}.bundle.scp.css
, kde zástupné symboly mají následující hodnoty:
{STATIC WEB ASSET BASE PATH}
: Základní cesta ke statickým webovým prostředkům.{PACKAGE ID}
: Identifikátor balíčku knihovny. Pokud identifikátor balíčku není zadaný v souboru projektu, ve výchozím nastavení se jako identifikátor balíčku použije název sestavení projektu.
V následujícím příkladu:
- Základní cesta ke statickým webovým prostředkům je
_content/ClassLib
. - Název sestavení knihovny tříd je
ClassLib
.
Pages/Shared/_Layout.cshtml
(Razor Pages) nebo Views/Shared/_Layout.cshtml
(MVC):
<link href="_content/ClassLib/ClassLib.bundle.scp.css" rel="stylesheet">
Další informace o knihovnách tříd Razor najdete v následujících článcích:
- Opakovaně použitelné uživatelské rozhraní Razor v knihovnách tříd s využitím ASP.NET Core
- Využívání komponent ASP.NET Core Razor v knihovně tříd Razor (RCL)
Informace o izolaci šablon stylů CSS v architektuře Blazor najdete v tématu Izolace šablon stylů CSS v architektuře ASP.NET Core Blazor.
Zpracování požadavků HEAD s využitím záložní obslužné rutiny OnGet
Požadavky HEAD
umožňují načtení hlaviček pro konkrétní prostředek. Na rozdíl od požadavků GET
požadavky HEAD
nevracejí text odpovědi.
Pro požadavky HEAD
se obvykle vytváří a volá obslužná rutina OnHead
:
public void OnHead()
{
HttpContext.Response.Headers.Add("Head Test", "Handled by OnHead!");
}
Pokud obslužná rutina OnHead
není definovaná, Razor Pages se vrátí k volání obslužné rutiny OnGet
.
XSRF/CSRF a Razor Pages
Stránky Razor jsou chráněné ověřováním proti padělkům. Obslužná rutina značky form vkládá do elementů formulářů HTML tokeny proti padělkům.
Používání rozložení, částečných zobrazení, šablon a obslužných rutin značek s Razor Pages
Stránky fungují se všemi funkcemi zobrazovacího modulu Razor. Rozložení, částečná zobrazení, šablony, obslužné rutiny značek a soubory _ViewStart.cshtml
a _ViewImports.cshtml
fungují stejně jako v běžných zobrazeních Razor.
Pojďme tuto stránku zpřehlednit s využitím některých z těchto funkcí.
Přidejte stránku rozložení do souboru Pages/Shared/_Layout.cshtml
:
<!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í rozložení každé stránky (pokud stránka rozložení výslovně neodmítne).
- Importuje struktury HTML, jako jsou JavaScript nebo šablony stylů.
- Při zavolání metody
@RenderBody()
vykreslí obsah stránky Razor.
Další informace najdete v tématu věnovaném stránce rozložení.
Hodnota Layout se nastavuje v souboru Pages/_ViewStart.cshtml
:
@{
Layout = "_Layout";
}
Rozložení se nachází ve složce Pages/Shared. Stránky hierarchicky hledají další zobrazení (rozložení, šablony, částečná zobrazení) počínaje stejnou složkou, ve které se nachází aktuální stránka. Rozložení ve složce Pages/Shared je možné použít na jakékoli stránce Razor ve složce Pages.
Soubor rozložení by se měl nacházet ve složce Pages/Shared.
Doporučujeme neumisťovat soubor rozložení do složky Views/Shared. Složka Views/Shared se používá pro model zobrazení MVC. Stránky Razor se mají spoléhat na hierarchii složek, a ne na konvence cest.
Vyhledávání zobrazení na stránce Razor zahrnuje i složku Pages. Rozložení, šablony a částečná zobrazení používaná s kontrolery MVC a běžnými zobrazeními Razor prostě fungují.
Přidejte soubor Pages/_ViewImports.cshtml
:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Direktivě @namespace
se věnujeme dále v tomto kurzu. Direktiva @addTagHelper
na všech stránkách ve složce Pages zpřístupní předdefinované obslužné rutiny značek.
Nastavená direktiva @namespace
na stránce:
@page
@namespace RazorPagesIntro.Pages.Customers
@model NameSpaceModel
<h2>Name space</h2>
<p>
@Model.Message
</p>
Direktiva @namespace
nastaví pro stránku obor názvů. Direktiva @model
nemusí obsahovat obor názvů.
Pokud soubor _ViewImports.cshtml
obsahuje direktivu @namespace
, zadaný obor názvů bude představovat předponu vygenerovaného oboru názvů na stránce, která importuje direktivu @namespace
. Vygenerovaný rest obor názvů (část s příponou) je tečkovaná relativní cesta mezi složkou obsahující _ViewImports.cshtml
a složkou obsahující stránku.
Například třída PageModel
v souboru Pages/Customers/Edit.cshtml.cs
explicitně nastaví obor názvů:
namespace RazorPagesContacts.Pages
{
public class EditModel : PageModel
{
private readonly AppDbContext _db;
public EditModel(AppDbContext db)
{
_db = db;
}
// Code removed for brevity.
V souboru Pages/_ViewImports.cshtml
se nastaví následující obor názvů:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Vygenerovaný obor názvů pro stránku Razor Pages/Customers/Edit.cshtml
bude stejný jako obor názvů třídy PageModel
.
@namespace
funguje také s konvenčními Razor zobrazeními.
Podívejte se například na soubor zobrazení Pages/Customers/Create.cshtml
:
@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>
Aktualizovaný soubor zobrazení Pages/Customers/Create.cshtml
se souborem _ViewImports.cshtml
a výše uvedeným souborem rozložení:
@page
@model CreateModel
<p>Enter a customer name:</p>
<form method="post">
Name:
<input asp-for="Customer!.Name" />
<input type="submit" />
</form>
Ve výše uvedeném kódu soubor _ViewImports.cshtml
importoval obor názvů a obslužné rutiny značek. Soubor rozložení importoval soubory JavaScriptu.
Úvodní projekt Razor Pages obsahuje soubor Pages/_ValidationScriptsPartial.cshtml
, který aktivuje ověřování na straně klienta.
Další informace o částečných zobrazeních najdete v tématu Částečná zobrazení v ASP.NET Core.
Generování adres URL pro stránky
Na stránce Create
uvedené výše se používá metoda RedirectToPage
:
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");
}
}
Aplikace má následující strukturu složek a souborů:
/Pages
Index.cshtml
Privacy.cshtml
/Customers
Create.cshtml
Edit.cshtml
Index.cshtml
Stránky Pages/Customers/Create.cshtml
a Pages/Customers/Edit.cshtml
se v případě úspěchu přesměrují na stránku Pages/Customers/Index.cshtml
. Řetězec ./Index
je relativní název stránky, který se používá pro přístup k předchozí stránce. Slouží ke generování adres URL na stránku Pages/Customers/Index.cshtml
. Příklad:
Url.Page("./Index", ...)
<a asp-page="./Index">Customers Index Page</a>
RedirectToPage("./Index")
Absolutní název stránky /Index
slouží ke generování adres URL na stránku Pages/Index.cshtml
. Příklad:
Url.Page("/Index", ...)
<a asp-page="/Index">Home Index Page</a>
RedirectToPage("/Index")
Název stránky představuje cestu ke stránce z kořenové složky /Pages včetně počátečního lomítka /
(například /Index
). Výše uvedené ukázky generování adres URL nabízejí oproti pevnému zakódování adresy URL rozšířené možnosti a funkce. Generování adres URL využívá směrování a dokáže generovat a kódovat parametry v závislosti na tom, jak je trasa definovaná v cílové cestě.
Generování adres URL pro stránky podporuje relativní názvy. Následující tabulka ukazuje, jaká indexová stránka se vybere při použití různých parametrů RedirectToPage
v souboru Pages/Customers/Create.cshtml
.
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")
a RedirectToPage("../Index")
jsou relativní názvy. Parametr RedirectToPage
se za účelem určení názvu cílové stránky kombinuje s cestou k aktuální stránce.
Odkazování pomocí relativních názvů je užitečné při vytváření webů se složitou strukturou. Pokud se k propojení mezi stránkami ve složce používají relativní názvy:
- Přejmenování složky neporuší relativní odkazy.
- Odkazy se neporuší, protože nezahrnují název složky.
Pokud chcete provést přesměrování na stránku v jiné oblasti, zadejte oblast:
RedirectToPage("/Index", new { area = "Services" });
Další informace najdete v tématech Oblasti v ASP.NET Core a Konvence směrování a aplikací Razor Pages v ASP.NET Core.
Atribut ViewData
Pomocí třídy ViewDataAttribute je možné na stránku předat data. Hodnoty vlastností s atributem [ViewData]
se uchovávají v třídě ViewDataDictionary, ze které se také načítají.
V následujícím příkladu třída AboutModel
používá atribut [ViewData]
u vlastnosti Title
:
public class AboutModel : PageModel
{
[ViewData]
public string Title { get; } = "About";
public void OnGet()
{
}
}
Na stránce About můžete k vlastnosti Title
přistupovat jako k vlastnosti modelu:
<h1>@Model.Title</h1>
V rozložení se název přečte ze slovníku ViewData:
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"] - WebApplication</title>
...
TempData
ASP.NET Core zpřístupňuje vlastnost TempData. Tato vlastnost zajišťuje uchovávání dat, dokud se nepřečtou. Ke zkoumání dat, aniž by došlo k jejich odstranění, je možné použít metody Keep a Peek. Vlastnost TempData
je užitečná pro přesměrování, kdy se data vyžadují pro více než jeden požadavek.
Následující kód nastaví hodnotu Message
s použitím vlastnosti TempData
:
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");
}
}
Následující kód v souboru Pages/Customers/Index.cshtml
zobrazí hodnotu Message
s použitím vlastnosti TempData
.
<h3>Msg: @Model.Message</h3>
Model stránky Pages/Customers/Index.cshtml.cs
použije atribut [TempData]
na vlastnost Message
.
[TempData]
public string Message { get; set; }
Další informace najdete v části TempData.
Více obslužných rutin na stránku
Následující stránka vygeneruje kód pro dvě obslužné rutiny s použitím obslužné rutiny značky asp-page-handler
:
@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>
Formulář ve výše uvedeném příkladu obsahuje dvě tlačítka pro odeslání, z nichž každé používá obslužnou rutinu FormActionTagHelper
k odeslání formuláře na jinou adresu URL. Atribut asp-page-handler
doplňuje atribut asp-page
. Atribut asp-page-handler
vygeneruje adresy URL, které se odešlou do všech metod obslužných rutin definovaných na stránce. Atribut asp-page
není zadaný, protože ukázka odkazuje na aktuální stránku.
Model stránky:
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();
}
}
}
Ve výše uvedeném kódu se používají pojmenované metody obslužných rutin. Názvy pojmenovaných metod obslužných rutin se vytvářejí z textu v názvu mezi On<HTTP Verb>
a Async
(pokud je k dispozici). Ve výše uvedeném příkladu jsou na stránce metody OnPostJoinListAsync a OnPostJoinListUCAsync. Po odebrání OnPost a Async jsou názvy obslužných rutin JoinList
a JoinListUC
.
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
Ve výše uvedeném kódu se pro odesílání do metody OnPostJoinListAsync
používá cesta URL https://localhost:5001/Customers/CreateFATH?handler=JoinList
. Pro odesílání do metody OnPostJoinListUCAsync
se používá cesta URL https://localhost:5001/Customers/CreateFATH?handler=JoinListUC
.
Vlastní trasy
Direktiva @page
umožňuje:
- Zadat vlastní trasu ke stránce. Například pomocí direktivy
@page "/Some/Other/Path"
můžete nastavit trasu ke stránce About na/Some/Other/Path
. - Připojit segmenty k výchozí trase stránky. Například pomocí direktivy
@page "item"
můžete do výchozí trasy stránky přidat segment item. - Připojit parametry k výchozí trase stránky. Například při použití direktivy
@page "{id}"
se může pro stránku vyžadovat parametr ID (id
).
Podporuje se relativní cesta vzhledem ke kořenovému adresáři určená znakem tildy (~
) na začátku trasy. Například trasa @page "~/Some/Other/Path"
je stejná jako @page "/Some/Other/Path"
.
Pokud se vám nelíbí řetězec dotazu ?handler=JoinList
v adrese URL, změňte trasu tak, že název obslužné rutiny umístíte do části adresy URL s cestou. Trasu můžete upravit přidáním šablony trasy v dvojitých uvozovkách za direktivu @page
.
@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>
Ve výše uvedeném kódu se pro odesílání do metody OnPostJoinListAsync
používá cesta URL https://localhost:5001/Customers/CreateFATH/JoinList
. Pro odesílání do metody OnPostJoinListUCAsync
se používá cesta URL https://localhost:5001/Customers/CreateFATH/JoinListUC
.
Symbol ?
za parametrem handler
znamená, že je tento parametr trasy volitelný.
Umístění souborů JavaScriptu (JS)
Umístění souborů JavaScriptu (JS) pro stránky a zobrazení je pohodlný způsob, jak uspořádat skripty v aplikaci.
Soubory JS umístěte společně s využitím následujících konvencí přípon názvů souborů:
- Stránky aplikací Razor Pages a zobrazení aplikací MVC:
.cshtml.js
. Příklady:Pages/Index.cshtml.js
pro stránkuIndex
aplikace Razor Pages vPages/Index.cshtml
Views/Home/Index.cshtml.js
pro zobrazeníIndex
aplikace MVC vViews/Home/Index.cshtml
Společně umístěné soubory JS jsou veřejně adresovatelné pomocí cesty k souborům v projektu:
Stránky a zobrazení ze souboru kompletovaných skriptů v aplikaci:
{PATH}/{PAGE, VIEW, OR COMPONENT}.{EXTENSION}.js
- Zástupný symbol
{PATH}
je cesta ke stránce, zobrazení nebo komponentě. - Zástupný symbol
{PAGE, VIEW, OR COMPONENT}
je příslušná stránka, zobrazení nebo komponenta. - Zástupný symbol
{EXTENSION}
odpovídá rozšíření stránky, zobrazení nebo komponenty, buďrazor
, nebocshtml
.
Příklad Razor Pages:
Soubor JS pro stránku
Index
je umístěný ve složcePages
(Pages/Index.cshtml.js
) vedle stránkyIndex
(Pages/Index.cshtml
). Na stránceIndex
se na skript odkazuje v cestě k složcePages
:@section Scripts { <script src="~/Pages/Index.cshtml.js"></script> }
- Zástupný symbol
Výchozí rozložení Pages/Shared/_Layout.cshtml
je možné nakonfigurovat tak, aby zahrnovalo kompletované JS soubory, což eliminuje nutnost konfigurovat jednotlivé stránky:
<script asp-src-include="@(ViewContext.View.Path).js"></script>
Stažení ukázky používá předchozí fragment kódu k zahrnutí kompletovaných JS souborů do výchozího rozložení.
Když je aplikace publikovaná, architektura automaticky přesune skript do webového kořenového adresáře. V předchozím příkladu se skript přesune do bin\Release\{TARGET FRAMEWORK MONIKER}\publish\wwwroot\Pages\Index.cshtml.js
, kde zástupný symbol {TARGET FRAMEWORK MONIKER}
je moniker cílové architektury (TFM). Nevyžaduje se žádná změna relativní adresy URL na stránce Index
.
Když je aplikace publikovaná, architektura automaticky přesune skript do webového kořenového adresáře. V předchozím příkladu se skript přesune do bin\Release\{TARGET FRAMEWORK MONIKER}\publish\wwwroot\Components\Pages\Index.razor.js
, kde zástupný symbol {TARGET FRAMEWORK MONIKER}
je moniker cílové architektury (TFM). Nevyžaduje se žádná změna relativní adresy URL v komponentě Index
.
Skripty poskytované knihovnou tříd Razor (RCL):
_content/{PACKAGE ID}/{PATH}/{PAGE, VIEW, OR COMPONENT}.{EXTENSION}.js
- Zástupný symbol
{PACKAGE ID}
je identifikátor balíčku RCL (nebo název knihovny tříd, na kterou aplikace odkazuje). - Zástupný symbol
{PATH}
je cesta ke stránce, zobrazení nebo komponentě. Pokud je komponenta Razor umístěná v kořenovém adresáři knihovny RCL, segment cesty není zahrnutý. - Zástupný symbol
{PAGE, VIEW, OR COMPONENT}
je příslušná stránka, zobrazení nebo komponenta. - Zástupný symbol
{EXTENSION}
odpovídá rozšíření stránky, zobrazení nebo komponenty, buďrazor
, nebocshtml
.
- Zástupný symbol
Pokročilá konfigurace a upřesňující nastavení
Pro většinu aplikací se konfigurace a nastavení v následujících částech nevyžadují.
Pokud chcete konfigurovat upřesňující nastavení použijte přetížení AddRazorPages, které konfiguruje objekt RazorPagesOptions:
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();
Pomocí objektu RazorPagesOptions můžete pro stránky nastavit kořenový adresář nebo přidat konvence modelu aplikace. Další informace o konvencích najdete v tématu Konvence autorizace Razor Pages.
Pokud chcete předkompilovat zobrazení, projděte si téma Kompilace zobrazení Razor.
Určení, že se stránky Razor Pages nacházejí v kořenovém adresáři obsahu
Ve výchozím nastavení je kořenovým adresářem Razor Pages adresář /Pages. Pokud chcete určit, že se vaše stránky Razor Pages nacházejí v kořenovém adresáři obsahu (ContentRootPath) aplikace, přidejte metodu WithRazorPagesAtContentRoot:
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();
Určení, že se stránky Razor Pages nacházejí ve vlastním kořenovém adresáři
Pokud chcete určit, že se stránky Razor Pages nacházejí ve vlastním kořenovém adresáři v rámci aplikace, přidejte metodu WithRazorPagesRoot (zadejte relativní cestu):
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();
Další materiály
- Projděte si kurz Začínáme s Razor Pages, který vychází z tohoto úvodu.
- Atribut Authorize a Razor Pages
- Stažení nebo zobrazení vzorového kódu
- Přehled ASP.NET Core
- Referenční informace k syntaxi Razor pro ASP.NET Core
- Oblasti v ASP.NET Core
- Kurz: Začínáme s Razor Pages v ASP.NET Core
- Konvence autorizace Razor Pages v ASP.NET Core
- Konvence směrování a aplikací Razor Pages v ASP.NET Core
- Testy jednotek Razor Pages v ASP.NET Core
- Částečná zobrazení v ASP.NET Core
- Sada Visual Studio 2019 16.4 nebo novější se sadou funkcí Vývoj pro ASP.NET a web
- Sada .NET Core 3.1 SDK
- Sada Visual Studio 2019 16.8 nebo novější se sadou funkcí Vývoj pro ASP.NET a web
- Sada .NET 5.0 SDK
Vytvoření projektu Razor Pages
Podrobné pokyny k vytvoření projektu Razor Pages najdete v tématu Začínáme s Razor Pages.
Razor Pages
Razor Pages se povoluje v souboru Startup.cs
:
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();
});
}
}
Podívejte se například na základní stránku:
@page
<h1>Hello, world!</h1>
<h2>The time on the server is @DateTime.Now</h2>
Výše uvedený kód se velmi podobá souboru zobrazení Razor, který se používá v aplikacích ASP.NET Core s kontrolery a zobrazeními. Liší se v direktivě @page
. Direktiva @page
ze souboru udělá akci MVC – to znamená, že bude zpracovávat požadavky přímo, aniž by procházely kontrolerem. Direktiva @page
musí být první direktivou Razor na stránce. Direktiva @page
ovlivňuje chování dalších konstrukcí Razor. Názvy souborů Razor Pages mají příponu .cshtml
.
V následujících dvou souborech je ukázka podobné stránky s použitím třídy PageModel
. Soubor Pages/Index2.cshtml
:
@page
@using RazorPagesIntro.Pages
@model Index2Model
<h2>Separate page model</h2>
<p>
@Model.Message
</p>
Model stránky Pages/Index2.cshtml.cs
:
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 }";
}
}
}
Podle konvence má soubor třídy PageModel
stejný název jako soubor stránky Razor s příponou .cs
. Například výše uvedená stránka Razor se nachází v souboru Pages/Index2.cshtml
. Soubor obsahující třídu PageModel
má název Pages/Index2.cshtml.cs
.
Přidružení cest URL ke stránkám se určuje podle umístění stránky v systému souborů. Následující tabulka ukazuje cestu ke stránce Razor a odpovídající adresu URL:
Název souboru a cesta | Odpovídající adresa URL |
---|---|
/Pages/Index.cshtml |
/ nebo /Index |
/Pages/Contact.cshtml |
/Contact |
/Pages/Store/Contact.cshtml |
/Store/Contact |
/Pages/Store/Index.cshtml |
/Store nebo /Store/Index |
Poznámky:
- Modul runtime ve výchozím nastavení hledá soubory Razor Pages ve složce Pages.
- Pokud adresa URL neobsahuje žádnou stránku, výchozí stránka je
Index
.
Napsání základního formuláře
Model Razor Pages je navržený tak, aby při vytváření aplikace usnadňoval implementaci běžných modelů používaných ve webových prohlížečích. Vazba modelu, pomocné rutiny značek a pomocné rutiny HTML prostě fungují s vlastnostmi definovanými v třídě stránky Razor. Podívejte se například na stránku, která pro model Contact
implementuje základní kontaktní formulář:
Pro ukázky v tomto dokumentu se DbContext
inicializuje v souboru Startup.cs.
Databáze v paměti vyžaduje balíček NuGet Microsoft.EntityFrameworkCore.InMemory
.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CustomerDbContext>(options =>
options.UseInMemoryDatabase("name"));
services.AddRazorPages();
}
Datový model:
using System.ComponentModel.DataAnnotations;
namespace RazorPagesContacts.Models
{
public class Customer
{
public int Id { get; set; }
[Required, StringLength(10)]
public string Name { get; set; }
}
}
Kontext databáze:
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; }
}
}
Soubor zobrazení Pages/Create.cshtml
:
@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>
Model stránky Pages/Create.cshtml.cs
:
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");
}
}
}
Podle konvence má třída PageModel
název <PageName>Model
a nachází se ve stejném oboru názvů jako stránka.
Třída PageModel
umožňuje oddělit logiku stránky od její prezentace. Definuje obslužné rutiny stránky pro požadavky odeslané na stránku a pro data použitá k vykreslení stránky. Toto oddělení umožňuje:
- Správu závislostí stránky prostřednictvím injektáže závislostí
- Testování jednotek
Stránka má metodu obslužné OnPostAsync
rutiny, která se spouští na POST
žádostech (když uživatel publikuje formulář). Je možné přidat metody obslužných událostí pro jakékoli příkazy HTTP. Nejběžnější obslužné rutiny jsou:
OnGet
pro inicializaci stavu potřebného pro stránku. Ve výše uvedeném kódu metodaOnGet
zobrazí stránku RazorCreateModel.cshtml
.OnPost
pro zpracování odesílání formulářů.
Přípona názvu Async
je volitelná, ale často se podle konvence používá pro asynchronní funkce. Výše uvedený kód je pro Razor Pages typický.
Pokud máte zkušenosti s aplikacemi ASP.NET využívajícími kontrolery a zobrazení:
- Kód metody
OnPostAsync
ve výše uvedeném příkladu se podobá typickému kódu kontroleru. - Většina primitiv MVC, jako jsou vazba modelu, ověřování a výsledky akcí, funguje v Razor Pages stejně jako u kontrolerů.
Výše uvedená metoda OnPostAsync
:
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
_context.Customers.Add(Customer);
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
Základní tok metody OnPostAsync
:
Zkontroluje, jestli nedošlo k chybám ověřování.
- Pokud nedošlo k žádným chybám, uloží data a provede přesměrování.
- Pokud došlo k chybám, znovu zobrazí stránku s ověřovacími zprávami. V mnoha případech by se v klientovi zjistily chyby ověřování a nikdy by se neodeslaly na server.
Soubor zobrazení Pages/Create.cshtml
:
@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>
Vykreslený kód HTML ze souboru Pages/Create.cshtml
:
<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>
Ve výše uvedeném kódu se po odeslání formuláře stane následující:
V případě platných dat:
Metoda obslužné rutiny
OnPostAsync
zavolá metodu obslužné rutiny RedirectToPage.RedirectToPage
vrací instanci RedirectToPageResult.RedirectToPage
:- Je výsledek akce.
- Je metoda podobná metodám
RedirectToAction
neboRedirectToRoute
(které se používají v kontrolerech a zobrazeních). - Je metoda přizpůsobená pro stránky. Ve výše uvedené ukázce provádí přesměrování na kořenovou indexovou stránku (
/Index
). MetodaRedirectToPage
je podrobně popsaná v části Generování adres URL pro stránky.
V případě chyb ověřování předaných na server:
- Metoda obslužné rutiny
OnPostAsync
zavolá metodu obslužné rutiny Page.Page
vrací instanci PageResult. Vrácení objektuPage
se podobá tomu, jak akce v kontrolerech vrací objektView
. Výchozí návratový typ metody obslužné rutiny jePageResult
. Metoda obslužné rutiny, která vrátí hodnotuvoid
, vykreslí stránku. - Ve výše uvedeném příkladu odeslání formuláře bez jakékoli hodnoty způsobí, že ModelState.IsValid vrátí hodnotu false. V této ukázce se v klientovi nezobrazí žádné chyby ověřování. Zpracování chyb ověřování se věnujeme dále v tomto dokumentu.
public async Task<IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return Page(); } _context.Customers.Add(Customer); await _context.SaveChangesAsync(); return RedirectToPage("./Index"); }
- Metoda obslužné rutiny
V případě detekce chyb ověřování při ověřování na straně klienta:
- Data se neodešlou na server.
- Ověřování na straně klienta se věnujeme dále v tomto dokumentu.
Vlastnost Customer
pro přihlášení k vazbě modelu používá atribut [BindProperty]
:
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");
}
}
Atribut [BindProperty]
by se neměl používat u modelů obsahujících vlastnosti, které by klient neměl měnit. Další informace najdete v části Útoky typu overpost.
Razor Pages ve výchozím nastavení váže vlastnosti pouze k jiným příkazům než GET
. Díky vazbě na vlastnosti odpadá nutnost psát kód pro převod dat HTTP na typ modelu. Vazba snižuje množství kódu díky tomu, že se k vykreslení polí formuláře (<input asp-for="Customer.Name">
) a příjmu vstupu používá stejná vlastnost.
Upozorňující
Z bezpečnostních důvodů musíte vyjádřit souhlas s vazbou dat požadavků GET
na vlastnosti modelu stránky. Před mapováním uživatelského vstupu na vlastnosti tento vstup ověřte. Vyjádření souhlasu s vazbou požadavků GET
je užitečné při řešení scénářů, které se spoléhají na řetězec dotazu nebo hodnoty trasy.
Pokud chcete vytvořit vazbu vlastnosti na požadavky GET
, nastavte vlastnost SupportsGet
atributu [BindProperty]
na hodnotu true
:
[BindProperty(SupportsGet = true)]
Další informace najdete ve videu Přehled novinek v komunitě ASP.NET Core: Diskuze k vazbě požadavků GET (YouTube).
Projděte si soubor zobrazení Pages/Create.cshtml
:
@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>
- V předchozím kódu pomocné rutina
<input asp-for="Customer.Name" />
vstupní značky sváže element HTML<input>
s výrazemCustomer.Name
modelu. - Direktiva
@addTagHelper
zpřístupňuje pomocné rutiny značek.
Stránka home
Index.cshtml
home je stránka:
@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>
Přidružená třída PageModel
(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();
}
}
Soubor Index.cshtml
obsahuje následující kód:
<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> |
Pomocná rutina <a /a>
značky ukotvení použila asp-route-{value}
atribut k vygenerování odkazu na stránku Upravit. Odkaz obsahuje data trasy a ID kontaktu. Například https://localhost:5001/Edit/1
. Pomocné rutiny značek umožňují, aby se kód na straně serveru v souborech Razor podílel na vytváření a vykreslování elementů HTML.
Soubor Index.cshtml
obsahuje kód, který pro každý kontakt zákazníka vytvoří tlačítko pro odstranění:
<button type="submit" asp-page-handler="delete" asp-route-id="@contact.Id">delete</button>
Vykreslený kód HTML:
<button type="submit" formaction="/Customers?id=1&handler=delete">delete</button>
Když se tlačítko pro odstranění vykreslí v HTML, jeho atribut formaction obsahuje parametry pro:
- ID kontaktu zákazníka zadané atributem
asp-route-id
- Obslužnou rutinu
handler
zadanou atributemasp-page-handler
Při výběru tohoto tlačítka se na server odešle požadavek POST
formuláře. Podle konvence se název metody obslužné rutiny vybírá na základě hodnoty parametru handler
ve schématu OnPost[handler]Async
.
Vzhledem k tomu, že parametr handler
má v tomto příkladu hodnotu delete
, ke zpracování požadavku POST
se použije metoda obslužné rutiny OnPostDeleteAsync
. Pokud je atribut asp-page-handler
nastavený na jinou hodnotu, například remove
, vybere se metoda obslužné rutiny s názvem OnPostRemoveAsync
.
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();
}
Metoda OnPostDeleteAsync
:
- Získá z řetězce dotazu hodnotu
id
. - Pomocí metody
FindAsync
odešle do databáze dotaz na kontakt zákazníka. - Pokud se kontakt zákazníka najde, odebere se a databáze se aktualizuje.
- Zavolá metodu RedirectToPage, která provede přesměrování na kořenovou indexovou stránku (
/Index
).
Soubor Edit.cshtml
@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>
První řádek obsahuje direktivu @page "{id:int}"
. Omezení směrování "{id:int}"
stránce říká, že má přijímat požadavky na stránku, které obsahují data trasy typu int
. Pokud požadavek na stránku neobsahuje data trasy, která je možné převést na hodnotu typu int
, modul runtime vrátí chybu HTTP 404 (Nenalezeno). Pokud chcete nastavit ID jako volitelné, připojte k omezení trasy symbol ?
:
@page "{id:int?}"
Soubor Edit.cshtml.cs
:
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");
}
}
Ověřování
Pravidla ověřování:
- Zadávají se deklarativně v třídě modelu.
- Vynucují se v rámci celé aplikace.
Obor názvů System.ComponentModel.DataAnnotations nabízí sadu předdefinovaných atributů ověřování, které je možné deklarativně použít na třídu nebo vlastnost. Obor názvů DataAnnotations obsahuje také atributy formátování, jako je [DataType]
, které pomáhají s formátováním a neposkytují žádné ověřování.
Podívejte se například na model Customer
:
using System.ComponentModel.DataAnnotations;
namespace RazorPagesContacts.Models
{
public class Customer
{
public int Id { get; set; }
[Required, StringLength(10)]
public string Name { get; set; }
}
}
Používá se následující soubor zobrazení Create.cshtml
:
@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>
Předchozí kód:
Vkládá knihovnu jQuery a ověřovací skripty jQuery.
Pomocí pomocných rutin a
<span />
pomocných<div />
rutin značek povolíte:- Ověřování na straně klienta
- Vykreslování chyb ověřování
Generuje následující kód 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> <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>
Při odeslání formuláře pro vytvoření bez hodnoty názvu se ve formuláři zobrazí chybová zpráva Pole Name je povinné. Pokud je v klientovi povolený JavaScript, v prohlížeči se zobrazí chyba, aniž by se formulář odeslal na server.
Atribut [StringLength(10)]
ve vykresleném kódu HTML vygeneruje atribut data-val-length-max="10"
. Atribut data-val-length-max
brání v prohlížečích v zadání více znaků, než je zadaná maximální délka. Pokud se k úpravě a opětovnému odeslání použije nástroj typu Fiddler:
- Pokud je název delší než 10 znaků:
- Vrátí se chybová zpráva Pole Name musí obsahovat řetězec o maximální délce 10 znaků.
Podívejte se například na následující model 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; }
}
}
Atributy ověřování určují chování, které se má vynucovat u vlastností modelu, na které se použijí:
Atributy
Required
aMinimumLength
značí, že vlastnost musí mít nějakou hodnotu, ale uživateli nic nebrání v zadání prázdných znaků, které tímto ověřením projdou.Atribut
RegularExpression
slouží k omezení množiny znaků, které je možné zadat. Pro vlastnost Genre ve výše uvedeném kódu platí následující:- Může obsahovat pouze písmena.
- Počáteční písmeno musí být velké. Nemůže obsahovat prázdné znaky, číslice ani speciální znaky.
Regulární výraz (
RegularExpression
) u vlastnosti Rating:- Vyžaduje, aby prvním znakem bylo velké písmeno.
- Na dalších místech povoluje speciální znaky a číslice. PG-13 je platná hodnota pro vlastnost Rating, ale ne pro vlastnost Genre.
Atribut
Range
omezuje hodnotu v konkrétním rozsahu.Atribut
StringLength
nastavuje maximální délku řetězcové vlastnosti a volitelně i její minimální délku.Typy hodnot (například
decimal
,int
,float
,DateTime
) jsou ze své podstaty povinné a nevyžadují atribut[Required]
.
Na stránce pro vytvoření pro model Movie
se v případě neplatných hodnot zobrazí chyby:
Další informace naleznete v tématu:
Zpracování požadavků HEAD s využitím záložní obslužné rutiny OnGet
Požadavky HEAD
umožňují načtení hlaviček pro konkrétní prostředek. Na rozdíl od požadavků GET
požadavky HEAD
nevracejí text odpovědi.
Pro požadavky HEAD
se obvykle vytváří a volá obslužná rutina OnHead
:
public void OnHead()
{
HttpContext.Response.Headers.Add("Head Test", "Handled by OnHead!");
}
Pokud obslužná rutina OnHead
není definovaná, Razor Pages se vrátí k volání obslužné rutiny OnGet
.
XSRF/CSRF a Razor Pages
Stránky Razor jsou chráněné ověřováním proti padělkům. Obslužná rutina značky form vkládá do elementů formulářů HTML tokeny proti padělkům.
Používání rozložení, částečných zobrazení, šablon a obslužných rutin značek s Razor Pages
Stránky fungují se všemi funkcemi zobrazovacího modulu Razor. Rozložení, částečná zobrazení, šablony, obslužné rutiny značek a soubory _ViewStart.cshtml
a _ViewImports.cshtml
fungují stejně jako v běžných zobrazeních Razor.
Pojďme tuto stránku zpřehlednit s využitím některých z těchto funkcí.
Přidejte stránku rozložení do souboru Pages/Shared/_Layout.cshtml
:
<!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í rozložení každé stránky (pokud stránka rozložení výslovně neodmítne).
- Importuje struktury HTML, jako jsou JavaScript nebo šablony stylů.
- Při zavolání metody
@RenderBody()
vykreslí obsah stránky Razor.
Další informace najdete v tématu věnovaném stránce rozložení.
Hodnota Layout se nastavuje v souboru Pages/_ViewStart.cshtml
:
@{
Layout = "_Layout";
}
Rozložení se nachází ve složce Pages/Shared. Stránky hierarchicky hledají další zobrazení (rozložení, šablony, částečná zobrazení) počínaje stejnou složkou, ve které se nachází aktuální stránka. Rozložení ve složce Pages/Shared je možné použít na jakékoli stránce Razor ve složce Pages.
Soubor rozložení by se měl nacházet ve složce Pages/Shared.
Doporučujeme neumisťovat soubor rozložení do složky Views/Shared. Složka Views/Shared se používá pro model zobrazení MVC. Stránky Razor se mají spoléhat na hierarchii složek, a ne na konvence cest.
Vyhledávání zobrazení na stránce Razor zahrnuje i složku Pages. Rozložení, šablony a částečná zobrazení používaná s kontrolery MVC a běžnými zobrazeními Razor prostě fungují.
Přidejte soubor Pages/_ViewImports.cshtml
:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Direktivě @namespace
se věnujeme dále v tomto kurzu. Direktiva @addTagHelper
na všech stránkách ve složce Pages zpřístupní předdefinované obslužné rutiny značek.
Nastavená direktiva @namespace
na stránce:
@page
@namespace RazorPagesIntro.Pages.Customers
@model NameSpaceModel
<h2>Name space</h2>
<p>
@Model.Message
</p>
Direktiva @namespace
nastaví pro stránku obor názvů. Direktiva @model
nemusí obsahovat obor názvů.
Pokud soubor _ViewImports.cshtml
obsahuje direktivu @namespace
, zadaný obor názvů bude představovat předponu vygenerovaného oboru názvů na stránce, která importuje direktivu @namespace
. Vygenerovaný rest obor názvů (část s příponou) je tečkovaná relativní cesta mezi složkou obsahující _ViewImports.cshtml
a složkou obsahující stránku.
Například třída PageModel
v souboru Pages/Customers/Edit.cshtml.cs
explicitně nastaví obor názvů:
namespace RazorPagesContacts.Pages
{
public class EditModel : PageModel
{
private readonly AppDbContext _db;
public EditModel(AppDbContext db)
{
_db = db;
}
// Code removed for brevity.
V souboru Pages/_ViewImports.cshtml
se nastaví následující obor názvů:
@namespace RazorPagesContacts.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Vygenerovaný obor názvů pro stránku Razor Pages/Customers/Edit.cshtml
bude stejný jako obor názvů třídy PageModel
.
@namespace
funguje také s konvenčními Razor zobrazeními.
Podívejte se například na soubor zobrazení Pages/Create.cshtml
:
@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>
Aktualizovaný soubor zobrazení Pages/Create.cshtml
se souborem _ViewImports.cshtml
a výše uvedeným souborem rozložení:
@page
@model CreateModel
<p>Enter a customer name:</p>
<form method="post">
Name:
<input asp-for="Customer.Name" />
<input type="submit" />
</form>
Ve výše uvedeném kódu soubor _ViewImports.cshtml
importoval obor názvů a obslužné rutiny značek. Soubor rozložení importoval soubory JavaScriptu.
Úvodní projekt Razor Pages obsahuje soubor Pages/_ValidationScriptsPartial.cshtml
, který aktivuje ověřování na straně klienta.
Další informace o částečných zobrazeních najdete v tématu Částečná zobrazení v ASP.NET Core.
Generování adres URL pro stránky
Na stránce Create
uvedené výše se používá metoda RedirectToPage
:
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");
}
}
Aplikace má následující strukturu složek a souborů:
/Pages
Index.cshtml
Privacy.cshtml
/Customers
Create.cshtml
Edit.cshtml
Index.cshtml
Stránky Pages/Customers/Create.cshtml
a Pages/Customers/Edit.cshtml
se v případě úspěchu přesměrují na stránku Pages/Customers/Index.cshtml
. Řetězec ./Index
je relativní název stránky, který se používá pro přístup k předchozí stránce. Slouží ke generování adres URL na stránku Pages/Customers/Index.cshtml
. Příklad:
Url.Page("./Index", ...)
<a asp-page="./Index">Customers Index Page</a>
RedirectToPage("./Index")
Absolutní název stránky /Index
slouží ke generování adres URL na stránku Pages/Index.cshtml
. Příklad:
Url.Page("/Index", ...)
<a asp-page="/Index">Home Index Page</a>
RedirectToPage("/Index")
Název stránky představuje cestu ke stránce z kořenové složky /Pages včetně počátečního lomítka /
(například /Index
). Výše uvedené ukázky generování adres URL nabízejí oproti pevnému zakódování adresy URL rozšířené možnosti a funkce. Generování adres URL využívá směrování a dokáže generovat a kódovat parametry v závislosti na tom, jak je trasa definovaná v cílové cestě.
Generování adres URL pro stránky podporuje relativní názvy. Následující tabulka ukazuje, jaká indexová stránka se vybere při použití různých parametrů RedirectToPage
v souboru Pages/Customers/Create.cshtml
.
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")
a RedirectToPage("../Index")
jsou relativní názvy. Parametr RedirectToPage
se za účelem určení názvu cílové stránky kombinuje s cestou k aktuální stránce.
Odkazování pomocí relativních názvů je užitečné při vytváření webů se složitou strukturou. Pokud se k propojení mezi stránkami ve složce používají relativní názvy:
- Přejmenování složky neporuší relativní odkazy.
- Odkazy se neporuší, protože nezahrnují název složky.
Pokud chcete provést přesměrování na stránku v jiné oblasti, zadejte oblast:
RedirectToPage("/Index", new { area = "Services" });
Další informace najdete v tématech Oblasti v ASP.NET Core a Konvence směrování a aplikací Razor Pages v ASP.NET Core.
Atribut ViewData
Pomocí třídy ViewDataAttribute je možné na stránku předat data. Hodnoty vlastností s atributem [ViewData]
se uchovávají v třídě ViewDataDictionary, ze které se také načítají.
V následujícím příkladu třída AboutModel
používá atribut [ViewData]
u vlastnosti Title
:
public class AboutModel : PageModel
{
[ViewData]
public string Title { get; } = "About";
public void OnGet()
{
}
}
Na stránce About můžete k vlastnosti Title
přistupovat jako k vlastnosti modelu:
<h1>@Model.Title</h1>
V rozložení se název přečte ze slovníku ViewData:
<!DOCTYPE html>
<html lang="en">
<head>
<title>@ViewData["Title"] - WebApplication</title>
...
TempData
ASP.NET Core zpřístupňuje vlastnost TempData. Tato vlastnost zajišťuje uchovávání dat, dokud se nepřečtou. Ke zkoumání dat, aniž by došlo k jejich odstranění, je možné použít metody Keep a Peek. Vlastnost TempData
je užitečná pro přesměrování, kdy se data vyžadují pro více než jeden požadavek.
Následující kód nastaví hodnotu Message
s použitím vlastnosti TempData
:
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");
}
}
Následující kód v souboru Pages/Customers/Index.cshtml
zobrazí hodnotu Message
s použitím vlastnosti TempData
.
<h3>Msg: @Model.Message</h3>
Model stránky Pages/Customers/Index.cshtml.cs
použije atribut [TempData]
na vlastnost Message
.
[TempData]
public string Message { get; set; }
Další informace najdete v části TempData.
Více obslužných rutin na stránku
Následující stránka vygeneruje kód pro dvě obslužné rutiny s použitím obslužné rutiny značky asp-page-handler
:
@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>
Formulář ve výše uvedeném příkladu obsahuje dvě tlačítka pro odeslání, z nichž každé používá obslužnou rutinu FormActionTagHelper
k odeslání formuláře na jinou adresu URL. Atribut asp-page-handler
doplňuje atribut asp-page
. Atribut asp-page-handler
vygeneruje adresy URL, které se odešlou do všech metod obslužných rutin definovaných na stránce. Atribut asp-page
není zadaný, protože ukázka odkazuje na aktuální stránku.
Model stránky:
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();
}
}
}
Ve výše uvedeném kódu se používají pojmenované metody obslužných rutin. Názvy pojmenovaných metod obslužných rutin se vytvářejí z textu v názvu mezi On<HTTP Verb>
a Async
(pokud je k dispozici). Ve výše uvedeném příkladu jsou na stránce metody OnPostJoinListAsync a OnPostJoinListUCAsync. Po odebrání OnPost a Async jsou názvy obslužných rutin JoinList
a JoinListUC
.
<input type="submit" asp-page-handler="JoinList" value="Join" />
<input type="submit" asp-page-handler="JoinListUC" value="JOIN UC" />
Ve výše uvedeném kódu se pro odesílání do metody OnPostJoinListAsync
používá cesta URL https://localhost:5001/Customers/CreateFATH?handler=JoinList
. Pro odesílání do metody OnPostJoinListUCAsync
se používá cesta URL https://localhost:5001/Customers/CreateFATH?handler=JoinListUC
.
Vlastní trasy
Direktiva @page
umožňuje:
- Zadat vlastní trasu ke stránce. Například pomocí direktivy
@page "/Some/Other/Path"
můžete nastavit trasu ke stránce About na/Some/Other/Path
. - Připojit segmenty k výchozí trase stránky. Například pomocí direktivy
@page "item"
můžete do výchozí trasy stránky přidat segment item. - Připojit parametry k výchozí trase stránky. Například při použití direktivy
@page "{id}"
se může pro stránku vyžadovat parametr ID (id
).
Podporuje se relativní cesta vzhledem ke kořenovému adresáři určená znakem tildy (~
) na začátku trasy. Například trasa @page "~/Some/Other/Path"
je stejná jako @page "/Some/Other/Path"
.
Pokud se vám nelíbí řetězec dotazu ?handler=JoinList
v adrese URL, změňte trasu tak, že název obslužné rutiny umístíte do části adresy URL s cestou. Trasu můžete upravit přidáním šablony trasy v dvojitých uvozovkách za direktivu @page
.
@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>
Ve výše uvedeném kódu se pro odesílání do metody OnPostJoinListAsync
používá cesta URL https://localhost:5001/Customers/CreateFATH/JoinList
. Pro odesílání do metody OnPostJoinListUCAsync
se používá cesta URL https://localhost:5001/Customers/CreateFATH/JoinListUC
.
Symbol ?
za parametrem handler
znamená, že je tento parametr trasy volitelný.
Pokročilá konfigurace a upřesňující nastavení
Pro většinu aplikací se konfigurace a nastavení v následujících částech nevyžadují.
Pokud chcete konfigurovat upřesňující nastavení použijte přetížení AddRazorPages, které konfiguruje objekt RazorPagesOptions:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.RootDirectory = "/MyPages";
options.Conventions.AuthorizeFolder("/MyPages/Admin");
});
}
Pomocí objektu RazorPagesOptions můžete pro stránky nastavit kořenový adresář nebo přidat konvence modelu aplikace. Další informace o konvencích najdete v tématu Konvence autorizace Razor Pages.
Pokud chcete předkompilovat zobrazení, projděte si téma Kompilace zobrazení Razor.
Určení, že se stránky Razor Pages nacházejí v kořenovém adresáři obsahu
Ve výchozím nastavení je kořenovým adresářem Razor Pages adresář /Pages. Pokud chcete určit, že se vaše stránky Razor Pages nacházejí v kořenovém adresáři obsahu (ContentRootPath) aplikace, přidejte metodu WithRazorPagesAtContentRoot:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/MyPages/Admin");
})
.WithRazorPagesAtContentRoot();
}
Určení, že se stránky Razor Pages nacházejí ve vlastním kořenovém adresáři
Pokud chcete určit, že se stránky Razor Pages nacházejí ve vlastním kořenovém adresáři v rámci aplikace, přidejte metodu WithRazorPagesRoot (zadejte relativní cestu):
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/MyPages/Admin");
})
.WithRazorPagesRoot("/path/to/razor/pages");
}
Další materiály
- Projděte si kurz Začínáme s Razor Pages, který vychází z tohoto úvodu.
- Atribut Authorize a Razor Pages
- Stažení nebo zobrazení vzorového kódu
- Přehled ASP.NET Core
- Referenční informace k syntaxi Razor pro ASP.NET Core
- Oblasti v ASP.NET Core
- Kurz: Začínáme s Razor Pages v ASP.NET Core
- Konvence autorizace Razor Pages v ASP.NET Core
- Konvence směrování a aplikací Razor Pages v ASP.NET Core
- Testy jednotek Razor Pages v ASP.NET Core
- Částečná zobrazení v ASP.NET Core