Úvod do Razor stránek v ASP.NET Core

Rick Anderson a Ryan Nowak

Razor Stránky mohou usnadnit a produktivnější kódování scénářů zaměřených na stránky než používání kontrolerů a zobrazení.

Pokud hledáte kurz, který používá přístup model-zobrazení-kontroler, podívejte se na stránku Začínáme s ASP.NET Core MVC.

Tento dokument obsahuje úvod ke Razor stránkám. Není to podrobný kurz. Pokud zjistíte, že některé části jsou příliš pokročilé, podívejte se na stránku Začínáme se Razor stránkami. Přehled těchto ASP.NET Core v tématu Úvod do ASP.NET Core.

Požadavky

Vytvoření Razor projektu Pages

Podrobné pokyny Razor k vytvoření projektu Pages najdete v tématu Začínáme se Razor stránkami.

Razor Stránky

RazorStránky jsou povolené 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();
        });
    }
}

Zvažte základní stránku:

@page

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

Předchozí kód vypadá podobně jako soubor zobrazení použitý v aplikaci ASP.NET Core kontrolery Razor a zobrazeními. Čím se liší, je @page direktiva . @page zpracuje soubor do akce MVC – to znamená, že zpracovává požadavky přímo, aniž by prošel kontroleru. @page musí být první Razor direktivou na stránce. @page ovlivňuje chování jiných Razor konstruktorů. RazorNázvy souborů stránek mají příponu .cshtml.

Podobná stránka, která používá PageModel třídu , je znázorněna v následujících dvou souborech. 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 PageModel má soubor třídy stejný název jako Razor stránkovací soubor s připojeným souborem .cs. Například předchozí stránka je Razor Pages/Index2.cshtml. Soubor obsahující třídu PageModel má název Pages/Index2.cshtml.cs.

Přidružení cest URL k stránkám se určují podle umístění stránky v systému souborů. Následující tabulka obsahuje cestu ke stránce a Razor 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 Razor nastavení hledá soubory Pages ve složce Pages.
  • Index je výchozí stránka, pokud adresa URL neobsahuje stránku.

Vytvoření základního formuláře

Razor Stránky jsou navržené tak, aby běžné vzory používané ve webových prohlížečích byly při vytváření aplikace snadno implementované. Vazby modelu, pomocná zařízení značeka pomocná podpora HTML fungují jenom s vlastnostmi definovanými ve třídě Razor Page. Představte si stránku, která implementuje základní formulář "kontaktujte nás" Contact pro model:

Pro ukázky v tomto dokumentu DbContext se inicializuje v souboru Startup.cs.

Databáze v paměti vyžaduje Microsoft.EntityFrameworkCore.InMemory NuGet balíček.

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 je třída volána a PageModel je ve stejném oboru názvů jako <PageName>Model 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 data použitá k vykreslení stránky. Toto oddělení umožňuje:

Stránka má OnPostAsync metodu obslužné rutiny, která se spouští na POST žádostech (když uživatel odešle formulář). Je možné přidat metody obslužné rutiny pro jakýkoli příkaz HTTP. Nejběžnější obslužné rutiny jsou:

  • OnGet pro inicializaci stavu potřebného pro stránku. V předchozím kódu metoda OnGet zobrazí stránku CreateModel.cshtml. Razor
  • 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. Předchozí kód je pro Pages Razor typický.

Pokud jste obeznámeni s aplikacemi ASP.NET kontrolery a zobrazení:

  • Kód OnPostAsync v předchozím příkladu vypadá podobně jako typický kód kontroleru.
  • Většina primitiv MVC, jako jsou vazby modelu, ověřenía výsledky akce, funguje stejně s kontrolery a Razor stránkami.

Předchozí OnPostAsync metoda:

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

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

    return RedirectToPage("./Index");
}

Základní tok OnPostAsync :

Zkontrolujte chyby ověřování.

  • Pokud nejsou žádné chyby, uložte data a přesměrte je.
  • Pokud dojde k chybám, znovu zobrazte 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 stránky 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>

V předchozím kódu publikování formuláře:

  • S platnými daty:

    • Metoda OnPostAsync obslužné rutiny volá RedirectToPage pomocná metoda. RedirectToPage vrací instanci RedirectToPageResult. RedirectToPage:

      • Je výsledkem akce.
      • Je podobný nebo RedirectToAction RedirectToRoute (používá se v kontrolerů a zobrazeních).
      • Je přizpůsobená pro stránky. V předchozí ukázce se přesměruje na stránku kořenového indexu ( /Index ). RedirectToPage je podrobně popisuje generování adres URL pro oddíl Pages.
  • S chybami ověřování, které se předá serveru:

    • Metoda OnPostAsync obslužné rutiny volá Page pomocná metoda. Page vrací instanci PageResult. Vrácení se Page podobá tomu, jak akce v kontrolerů vrací View . PageResult je výchozí návratový typ pro metodu obslužné rutiny. Metoda obslužné rutiny, která vrací void , vykreslí stránku.
    • V předchozím příkladu publikování formuláře bez hodnoty vede k vrácení vlastnosti ModelState.IsValid s hodnotou false. V této ukázce se v klientovi nezobrazí žádné chyby ověřování. Předání chyb ověřování je prokryto 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");
    }
    
  • S chybami ověřování zjištěných ověřením na straně klienta:

    • Data se neúčtuje na server.
    • Ověření na straně klienta je vysvětleno dále v tomto dokumentu.

Vlastnost Customer používá atribut pro [BindProperty] výslovný souhlas s vazbou modelu:

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] by se neměly používat u modelů obsahujících vlastnosti, které by klient neměl měnit. Další informace najdete v tématu Overposting.

Razor Stránky ve výchozím nastavení svázat vlastnosti pouze s GET příkazy, které nejsou příkazy. Vazba na vlastnosti eliminuje potřebu zápisu kódu pro převod dat HTTP na typ modelu. Vazba redukuje kód použitím stejné vlastnosti pro vykreslení polí formuláře ( ) a <input asp-for="Customer.Name"> přijetí vstupu.

Upozornění

Z bezpečnostních důvodů musíte vyjádřit výslovný souhlas s vazbou GET dat požadavků na vlastnosti modelu stránky. Před mapováním uživatelského vstupu na vlastnosti ověřte vstup uživatele. Výslovný souhlas s GET vazbou je užitečný při řešení scénářů, které spoléhají na řetězec dotazu nebo hodnoty tras.

Pokud chcete vytvořit vazbu vlastnosti GET na požadavky, [BindProperty] nastavte vlastnost SupportsGet atributu na true :

[BindProperty(SupportsGet = true)]

Další informace najdete v tématu ASP.NET Core Community Standup: Bind on GET discussion (YouTube).

Kontrola souboru 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á metoda vstupní značky váže prvek <input asp-for="Customer.Name" /> HTML na výraz <input> Customer.Name modelu.
  • @addTagHelper z dostupných pomocníků značek.

Domovská stránka

Domovská stránka je Index.cshtml:

@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>

Přidružená PageModel třída (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:

<td>

Pomocná <a /a> nápověda značky ukotvení asp-route-{value} použila atribut k vygenerování odkazu na stránku pro úpravy. Odkaz obsahuje data trasy s ID kontaktu. Například, https://localhost:5001/Edit/1. Pomocná rozšíření značek umožňují, aby se kód na straně serveru mohl podílet na vytváření a vykreslování elementů HTML v Razor souborech.

Soubor Index.cshtml obsahuje kód pro vytvoření tlačítka pro odstranění pro každou kontaktní osobu zákazníka:

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

Vykreslený kód HTML:

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

Když se tlačítko odstranit vykreslí v HTML, akce formuláře bude obsahovat parametry pro:

  • ID kontaktu zákazníka, které určuje asp-route-id atribut .
  • , handler určené asp-page-handler atributem .

Když je tlačítko vybrané, požadavek POST na formulář se odesílá na server. Podle konvence je název metody obslužné rutiny vybrán na základě hodnoty handler parametru podle schématu OnPost[handler]Async .

Vzhledem k handler delete tomu, že je v tomto příkladu , metoda obslužné rutiny OnPostDeleteAsync se používá ke zpracování POST požadavku. Pokud je nastaven na jinou hodnotu, například , je vybrána metoda asp-page-handler obslužné rutiny s názvem remove 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á id z řetězce dotazu .
  • Dotazuje se databáze na kontakt zákazníka pomocí FindAsync .
  • Pokud je kontakt zákazníka nalezen, odebere se a databáze se aktualizuje.
  • Volání RedirectToPage pro přesměrování na stránku kořenového indexu ( /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 @page "{id:int}" direktivu . Omezení směrování říká "{id:int}" stránce, že má přijímat požadavky na stránku, která obsahuje int data tras. Pokud požadavek na stránku neobsahuje data tras, která je možné převést na , modul runtime vrátí chybu int HTTP 404 (nenašl se). Pokud chcete, aby bylo ID volitelné, ? připojte ho k omezení trasy:

@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í

Ověřovací pravidla:

  • Jsou deklarativní zadány ve třídě modelu.
  • Vynucuje se všude v aplikaci.

Obor názvů poskytuje sadu integrovaných atributů ověřování, System.ComponentModel.DataAnnotations které jsou použity deklarativně na třídu nebo vlastnost. DataAnnotations také obsahuje atributy formátování, jako jsou ty, které pomáhají s formátováním a [DataType] neposkytují žádné ověřování.

Vezměte v úvahu Customer model:

using System.ComponentModel.DataAnnotations;

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

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

Pomocí následujícího 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:

  • Zahrnuje ověřovací skripty jQuery a jQuery.

  • Pomocí <div /> pomocníků <span /> značek a povolí:

    • Ověřování na straně klienta.
    • Vykreslení chyby ověřování
  • Vygeneruje 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>
    

Publikováním hodnoty Vytvořit formulář bez názvu se zobrazí chybová zpráva Pole Název je povinné. ve formuláři. Pokud je v klientovi povolený JavaScript, prohlížeč zobrazí chybu bez odeslání na server.

Atribut [StringLength(10)] data-val-length-max="10" vygeneruje na vykreslené HTML. data-val-length-max brání prohlížeči v zadání většího počtu, než je zadaná maximální délka. Pokud se k úpravě a přehrávání příspěvku používá nástroj, jako je Fiddler:

  • S názvem delším než 10.
  • Chybová zpráva Název pole musí být řetězec s maximální délkou 10. .

Představte si následující Movie model:

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á vynutit u vlastností modelu, na které se aplikují:

  • Atributy Required a indikují, že vlastnost musí mít hodnotu, ale nic nebrání uživateli v zadání prázdného místa pro MinimumLength splnění tohoto ověření.

  • Atribut RegularExpression slouží k omezení znaků, které mohou být vstupem. V předchozím kódu je to Žánr:

    • Musí používat jenom písmena.
    • První písmeno musí být velké. Prázdné znaky, číslice a speciální znaky nejsou povolené.
  • RegularExpressionHodnocení:

    • Vyžaduje, aby první znak byl velké písmeno.
    • Povolí speciální znaky a čísla v následných mezerách. Pg-13 je platné pro hodnocení, ale selže u žánru.
  • Atribut Range omezuje hodnotu v konkrétním rozsahu.

  • Atribut nastaví maximální délku vlastnosti řetězce a volitelně StringLength její minimální délku.

  • Typy hodnot (například , , , ) jsou ze své podstaty povinné a decimal int float DateTime nepožaduji [Required] atribut .

Na stránce Vytvořit pro Movie model se zobrazí chyby s neplatnými hodnotami:

Formulář zobrazení filmů s několika chybami ověřování na straně klienta jQuery

Další informace naleznete v tématu:

Zpracování požadavků HEAD pomocí záložní obslužné rutiny OnGet

HEAD žádosti umožňují načítací hlavičky pro konkrétní prostředek. Na GET rozdíl od požadavků požadavky HEAD nevrací text odpovědi.

Obvykle se vytvoří OnHead obslužná rutina, která se volá pro HEAD požadavky:

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

Razor Pokud není definovaná žádná obslužná rutina, vrátí se stránka zpět k OnGet OnHead volání obslužné rutiny.

XSRF/CSRF Razor a stránky

RazorStránky jsou chráněné ověřením proti padělku. FormTagHelper vloží tokeny proti padělkům do prvků formuláře HTML.

Použití rozložení, částečných částí, šablon a pomocníků značek se Razor stránkami

Stránky fungují se všemi funkcemi Razor modulu zobrazení. Rozložení, částečná rozložení, šablony, pomocná rutina značek, _ViewStart.cshtml a _ViewImports.cshtml fungují stejně jako u konvenčních Razor zobrazení.

Pojďme tuto stránku zvýrazníme tím, že využijeme některé z těchto funkcí.

Přidejte stránku rozložení na stránky/sdílené/_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>

Rozložení:

  • Určuje rozložení jednotlivých stránek (Pokud stránka výslovný mimo rozložení).
  • Importuje struktury HTML, jako jsou JavaScript a StyleSheet.
  • Obsah Razor stránky se vykreslí tam, kde @RenderBody() se volá.

Další informace najdete v tématu rozložení stránky.

Vlastnost layout je nastavena na stránky/_ViewStart. cshtml:

@{
    Layout = "_Layout";
}

Rozložení se nachází na stránkách nebo ve sdílené složce. Stránky hledají další zobrazení (rozložení, šablony, částečné typy) hierarchicky a začínají ve stejné složce jako aktuální stránka. Rozložení na stránkách nebo ve sdílené složce můžete použít na libovolné Razor stránce ve složce stránky .

Soubor rozložení by měl přejít na stránky nebo do sdílené složky.

Nedoporučujeme umístit soubor rozložení do zobrazení/sdílené složky. Zobrazení/Shared je vzor zobrazení MVC. Razor Stránky mají sloužit k spoléhání se na hierarchii složek, nikoli na konvence cest.

Zobrazení hledání ze Razor stránky obsahuje složku stránky . Rozložení, šablony a částečné typy používané s řadiči MVC a konvenčními Razor zobrazeními fungují pouze.

Přidejte soubor Pages/_ViewImports. cshtml :

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

@namespace je vysvětleno dále v tomto kurzu. Tato @addTagHelper direktiva přináší předdefinované pomocníky značek všem stránkám ve složce Pages .

@namespaceDirektiva nastavená na stránce:

@page
@namespace RazorPagesIntro.Pages.Customers

@model NameSpaceModel

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

@namespaceDirektiva nastaví obor názvů pro stránku. @modelDirektiva nemusí zahrnovat obor názvů.

Pokud @namespace je direktiva obsažena v _ViewImports. cshtml, zadaný obor názvů poskytuje předponu pro generovaný obor názvů na stránce, která importuje @namespace direktivu. Zbytek generovaného oboru názvů (část přípony) je relativní cesta oddělená tečkou mezi složkou obsahující _ViewImports. cshtml a složkou obsahující stránku.

Například PageModel třídy 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.

Soubor Pages/_ViewImports. cshtml nastaví následující obor názvů:

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

Vygenerovaný obor názvů pro stránku Pages/Customers/Edit. cshtml Razor je stejný jako PageModel Třída.

@namespacefunguje také s konvenčními Razor zobrazeními.

Zvažte stránku zobrazení stránky/vytvořit soubor. 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 s _ViewImports. cshtml a předchozí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>

V předchozím kódu _ViewImports. cshtml importovala obor názvů a pomocníka značek. Soubor rozložení importoval soubory JavaScriptu.

Razor Úvodní projekt stránky obsahuje stránky/_ValidationScriptsPartial. cshtml, které se připojí k ověřování na straně klienta.

Další informace o částečných zobrazeních naleznete v tématu Částečná zobrazení v ASP.NET Core .

Generování adresy URL pro stránky

CreateStránka, která se zobrazuje dřív, používá 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 souborů nebo složek:

  • /Pages

    • Soubor Index.cshtml

    • Privacy. cshtml

    • /Customers

      • Vytvořit. cshtml
      • Upravit. cshtml
      • Soubor Index.cshtml

Stránky/zákazníci/vytvořit. cshtml a Pages/Customers/Edit. cshtml Pages přesměruje na Pages/Customers/index. cshtml po úspěchu. Řetězec ./Index je relativní název stránky, který slouží k přístupu na předchozí stránku. Slouží ke generování adres URL na stránce Pages/Customers/index. cshtml . Například:

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

Absolutní název stránky /Index se používá ke generování adres URL na stránce pages/index. cshtml . Například:

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

Název stránky je cesta ke stránce z kořenové složky /Pages , včetně úvodní / (například /Index ). Předchozí ukázky generování adresy URL nabízejí rozšířené možnosti a funkční funkce v rámci hardwarového kódování adresy URL. Generování adresy URL používá Směrování a může vygenerovat a kódovat parametry podle toho, jak je trasa definována v cílové cestě.

Generování adresy URL pro stránky podporuje relativní názvy. Následující tabulka ukazuje, která stránka index je vybrána pomocí různých RedirectToPage parametrů na stránkách/zákaznících/vytvořit. cshtml.

RedirectToPage (x) Stránka
RedirectToPage("/Index") Stránky/rejstřík
RedirectToPage("./Index"); Stránky/zákazníci/rejstřík
RedirectToPage(".. /Index") Stránky/rejstřík
RedirectToPage ("index") Stránky/zákazníci/rejstřík

RedirectToPage("Index"), RedirectToPage("./Index") a RedirectToPage("../Index") jsou relativní názvy. RedirectToPageParametr je kombinován s cestou aktuální stránky k výpočtu názvu cílové stránky.

Propojení relativního názvu je užitečné při vytváření webů se složitou strukturou. Když se k propojení mezi stránkami ve složce použijí relativní názvy:

  • Přejmenování složky neruší relativní odkazy.
  • Odkazy nejsou přerušeny, protože neobsahují název složky.

Chcete-li přesměrovat na stránku v jiné oblasti, zadejte oblast:

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

Další informace naleznete v tématech Oblasti v ASP.NET Core a RazorSměrování stránek a konvence aplikací v ASP.NET Core.

ViewData – atribut

Data je možné předat stránce pomocí ViewDataAttribute . Vlastnosti s [ViewData] atributem mají své hodnoty uložené a načtené z ViewDataDictionary .

V následujícím příkladu AboutModel použije [ViewData] atribut na Title vlastnost:

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

    public void OnGet()
    {
    }
}

Na stránce o aplikaci získáte přístup k Title vlastnosti jako vlastnost modelu:

<h1>@Model.Title</h1>

V rozložení je název čten ze slovníku ViewData:

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

TempData

ASP.NET Core zpřístupňuje TempData . Tato vlastnost ukládá data do jejich čtení. KeepMetody a Peek lze použít k prohlédnutí dat bez odstranění. TempData je vhodný pro přesměrování, pokud jsou potřebná data pro více než jeden požadavek.

Následující kód nastaví hodnotu Message pomocí 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 zobrazuje hodnotu Message using TempData .

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

Model stránky Pages/Customers/index. cshtml. cs aplikuje [TempData] atribut na Message vlastnost.

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

Další informace najdete v tématu TempData.

Více obslužných rutin na stránku

Následující stránka generuje značky pro dvě obslužné rutiny pomocí asp-page-handler pomocníka značky:

@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>

Formulář v předchozím příkladu obsahuje dvě tlačítka pro odeslání, z nichž každá používá FormActionTagHelper pro odeslání na jinou adresu URL. asp-page-handlerAtribut je doprovodný objekt k asp-page . asp-page-handler generuje adresy URL, které odesílají do každé z metod obslužné rutiny, které jsou definovány stránkou. asp-page není zadáno, 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();
        }
    }
}

Předchozí kód používá pojmenované obslužné rutiny. Pojmenované obslužné rutiny jsou vytvořeny pomocí textu v názvu po On<HTTP Verb> a před Async (Pokud je k dispozici). V předchozím příkladu jsou metody stránky JoinList Async a post JoinListUC Async. Když jsou rutiny post a Async odebrány, názvy obslužných rutin jsou JoinList a JoinListUC .

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

Pomocí předchozího kódu je cesta URL, na kterou se odesílá, OnPostJoinListAsync https://localhost:5001/Customers/CreateFATH?handler=JoinList . Cesta URL, na kterou se odesílá OnPostJoinListUCAsync https://localhost:5001/Customers/CreateFATH?handler=JoinListUC .

Vlastní trasy

Použijte tuto @page direktivu pro:

  • Zadejte vlastní trasu na stránku. Například trasa na stránku o aplikaci může být nastavena na /Some/Other/Path @page "/Some/Other/Path" .
  • Připojit segmenty k výchozí trase stránky. Například segment "položka" lze přidat do výchozí trasy stránky s @page "item" .
  • Připojení parametrů k výchozí trase stránky. Například parametr ID id může být požadován pro stránku s @page "{id}" .

Je podporována kořenová relativní cesta, která je určena vlnovkou ( ~ ) na začátku cesty. Například @page "~/Some/Other/Path" je stejný jako @page "/Some/Other/Path" .

Pokud se v adrese URL nelíbí řetězec dotazu ?handler=JoinList , změňte trasu tak, aby se název obslužné rutiny umístil do části cesty adresy URL. Trasa se dá přizpůsobit přidáním šablony trasy, která je uzavřená do dvojitých uvozovek za @page direktivou.

@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>

Pomocí předchozího kódu je cesta URL, na kterou se odesílá, OnPostJoinListAsync https://localhost:5001/Customers/CreateFATH/JoinList . Cesta URL, na kterou se odesílá OnPostJoinListUCAsync https://localhost:5001/Customers/CreateFATH/JoinListUC .

?Následující handler údaj znamená, že parametr trasy je nepovinný.

Pokročilá konfigurace a nastavení

Konfigurace a nastavení v následujících oddílech není pro většinu aplikací vyžadováno.

Pro konfiguraci pokročilých možností použijte AddRazorPages přetížení, které konfiguruje RazorPagesOptions :

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

Pomocí RazorPagesOptions můžete nastavit kořenový adresář pro stránky nebo přidat konvence modelu aplikace pro stránky. Další informace o konvencích najdete v tématu Razor autorizační konvence stránek.

Chcete-li předkompilovat zobrazení, přečtěte si téma Razor zobrazení kompilace.

Zadejte, jestli Razor se stránky nacházejí v kořenu obsahu.

Ve výchozím nastavení Razor se stránky rootují v adresáři /Pages . Přidat WithRazorPagesAtContentRoot k určení, že vaše Razor stránky jsou v kořenu obsahu ( ContentRootPath ) aplikace:

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

Zadejte, jestli Razor jsou stránky ve vlastním kořenovém adresáři.

Přidat WithRazorPagesRoot k určení, že Razor stránky jsou v aplikaci vlastním kořenovým adresářem (zadejte relativní cestu):

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

Další zdroje informací

Upozornění

Pokud používáte sadu Visual Studio 2017, přečtěte si článek dotnet/SDK výdeje #3124 pro informace o .NET Core SDK verzích, které nefungují se sadou Visual Studio.

Vytvořit Razor projekt stránek

Podrobné pokyny k vytvoření projektu stránky najdete v tématu Začínáme se Razor stránkami Razor .

Razor Stránky

Razor Stránky jsou povoleny při spuštění. cs:

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

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

Zvažte základní stránku:

@page

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

předchozí kód vypadá jako Razor soubor zobrazení používaný v aplikaci ASP.NET Core s řadiči a zobrazeními. To znamená, že tato direktiva je odlišná @page . @page Vytvoří soubor na akci MVC – to znamená, že zpracovává požadavky přímo, bez přechodu přes kontroler. @page musí se jednat o první Razor direktivu na stránce. @page má vliv na chování jiných Razor konstrukcí.

Podobná stránka, která používá PageModel třídu, je zobrazena v následujících dvou souborech. Soubor Pages/Index2. cshtml :

@page
@using RazorPagesIntro.Pages
@model IndexModel2

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

Model stránky stránky/Index2. cshtml. cs :

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

Podle konvence PageModel má soubor třídy stejný název jako Razor stránkovací soubor s příponou. cs . Například předchozí Razor stránka je Pages/Index2. cshtml. Soubor obsahující PageModel třídu má název Pages/Index2. cshtml. cs.

Přidružení cest URL ke stránkám závisí na umístění stránky v systému souborů. Následující tabulka ukazuje Razor cestu stránky a adresu URL pro porovnání:

Název souboru a cesta shodná 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 Razor ve výchozím nastavení vyhledá soubory stránek ve složce stránky .
  • Index je výchozí stránka, když adresa URL neobsahuje stránku.

Napsat základní formulář

Razor Stránky jsou navržené tak, aby při vytváření aplikace byly běžné vzory používané s webovými prohlížeči, které se dají snadno implementovat. Vazba modelů, pomocníky značeka HTML pomocníků pro HTML stačí pracovat s vlastnostmi definovanými ve Razor třídě stránky. Zvažte stránku, která pro model implementuje základní formulář "kontaktujte nás" Contact :

V případě ukázek v tomto dokumentu DbContext se inicializuje v souboru Startup. cs .

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

Datový model:

using System.ComponentModel.DataAnnotations;

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

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

Kontext databáze:

using Microsoft.EntityFrameworkCore;

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

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

Soubor zobrazení Pages/Create. cshtml :

@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>

Model stránky Pages/Create. cshtml. cs :

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

Podle konvence PageModel je třída volána <PageName>Model a je ve stejném oboru názvů jako stránka.

PageModelTřída umožňuje oddělení logiky stránky od její prezentace. Definuje obslužné rutiny stránky pro požadavky odeslané na stránku a data použitá k vykreslení stránky. Toto oddělení umožňuje:

Stránka obsahuje OnPostAsync metodu obslužné rutiny, která běží na POST žádostech (když uživatel formulář odešle). Můžete přidat metody obslužné rutiny pro jakýkoli příkaz HTTP. Nejběžnější obslužné rutiny jsou:

  • OnGet pro inicializaci stavu potřebného pro stránku. Ukázka OnGet
  • 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. Předchozí kód je typický pro Razor stránky.

pokud jste obeznámeni s ASP.NET aplikacemi pomocí řadičů a zobrazení:

  • OnPostAsyncKód v předchozím příkladu vypadá podobně jako typický kód kontroleru.
  • Většina primitivních prvků MVC, jako je vazba modelů, ověřování, ověřovánía výsledky akce, jsou sdílené.

Předchozí OnPostAsync metoda:

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

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

Základní tok OnPostAsync :

Kontrola chyb ověřování.

  • V případě, že nejsou k dispozici žádné chyby, uložte data a přesměrujte je.
  • Pokud dojde k chybám, zobrazte stránku znovu s ověřovacími zprávami. ověřování na straně klienta je stejné jako tradiční aplikace ASP.NET Core MVC. V mnoha případech by se v klientovi zjistily chyby ověřování a nikdy by se neodeslaly na server.

Po úspěšném zadání dat OnPostAsync zavolá metoda obslužné rutiny RedirectToPage pomocnou metodu, která vrátí instanci RedirectToPageResult . RedirectToPage je nový výsledek akce, který se podobá RedirectToAction nebo RedirectToRoute , ale přizpůsobený pro stránky. V předchozí ukázce přesměruje na stránku kořenového indexu ( /Index ). RedirectToPage je podrobně popsán v části generování adresy URL pro stránky .

Když odeslaný formulář obsahuje chyby ověřování (které jsou předány serveru), OnPostAsync Metoda obslužné rutiny volá Page pomocnou metodu. Page vrací instanci PageResult. Vrácení Page se podobá tomu, jak vrátí akce v řadičích View . PageResult je výchozí návratový typ pro metodu obslužné rutiny. Metoda obslužné rutiny, která vrací void vykreslení stránky.

CustomerVlastnost používá [BindProperty] atribut pro přihlášení k vazbě modelu.

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 Stránky, ve výchozím nastavení vlastnosti BIND pouze bez GET slovesa. Vazba na vlastnosti může snížit množství kódu, který musíte napsat. Vazba zkracuje kód pomocí stejné vlastnosti pro vykreslení polí formuláře ( <input asp-for="Customer.Name"> ) a přijměte vstup.

Upozornění

Z bezpečnostních důvodů musíte vyjádřit výslovný souhlas s vazbou GET dat požadavků na vlastnosti modelu stránky. Před mapováním uživatelského vstupu na vlastnosti ověřte vstup uživatele. Výslovný souhlas s GET vazbou je užitečný při řešení scénářů, které spoléhají na řetězec dotazu nebo hodnoty tras.

Pokud chcete vytvořit vazbu vlastnosti GET na požadavky, [BindProperty] nastavte vlastnost SupportsGet atributu na true :

[BindProperty(SupportsGet = true)]

Další informace najdete v tématu ASP.NET Core Community Standup: Bind on GET discussion (YouTube).

Domovská stránka (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>

Přidružená PageModel třída (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();
        }
    }
}

Soubor index. cshtml obsahuje následující kód pro vytvoření odkazu pro úpravy pro každý kontakt:

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

<a asp-page="./Edit" asp-route-id="@contact.Id">Edit</a> Pomocná značka značky použila asp-route-{value} atribut k vygenerování odkazu na stránku pro úpravy. Odkaz obsahuje data směrování s ID kontaktu. Například, https://localhost:5001/Edit/1. Pomáhat pomocníkům při vytváření kódu a vykreslování prvků HTML v souborech, které umožňují kód na straně serveru Razor Pomocník značek je povolený nástrojem @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Soubor Pages/Edit. cshtml :

@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>

První řádek obsahuje @page "{id:int}" direktivu. Omezení směrování "{id:int}" instruuje stránku, aby přijímala požadavky na stránku, která obsahuje int data směrování. Pokud požadavek na stránku neobsahuje směrovací data, která je možné převést na int , modul runtime vrátí chybu HTTP 404 (Nenalezeno). Pokud chcete ID nastavit jako volitelné, připojovat ? se k omezení trasy:

@page "{id:int?}"

Soubor Pages/Edit. cshtml. cs :

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

Soubor index. cshtml také obsahuje značky pro vytvoření tlačítka Odstranit pro kontaktování každého zákazníka:

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

Když je tlačítko Odstranit vykresleno ve formátu HTML, formaction obsahuje parametry pro:

  • ID kontaktu zákazníka určené asp-route-id atributem
  • handlerZadané asp-page-handler atributem.

Tady je příklad vygenerovaného tlačítka odstranit s ID kontaktu zákazníka 1 :

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

Když je vybráno tlačítko, POST pošle se na server požadavek na formulář. Podle konvence je název metody obslužné rutiny vybraný na základě hodnoty handler parametru podle schématu OnPost[handler]Async .

Vzhledem k handler delete tomu, že je v tomto příkladu, OnPostDeleteAsync Metoda obslužné rutiny se používá ke zpracování POST požadavku. Pokud asp-page-handler je nastaven na jinou hodnotu, například remove , je vybrána metoda obslužné rutiny s názvem OnPostRemoveAsync . Následující kód ukazuje OnPostDeleteAsync obslužnou rutinu:

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

OnPostDeleteAsyncMetoda:

  • Akceptuje id z řetězce dotazu. Pokud direktiva stránky index. cshtml obsahuje omezení směrování "{id:int?}" , id pocházela z dat směrování. Data trasy pro id se zadává v identifikátoru URI, jako je například https://localhost:5001/Customers/2 .
  • Dotazuje databázi na kontaktování zákazníka FindAsync .
  • Pokud se kontakt zákazníka najde, odebere se ze seznamu kontaktů zákazníka. Databáze je aktualizována.
  • Volání RedirectToPage pro přesměrování na stránku kořenového indexu ( /Index ).

Označit vlastnosti stránky jako povinné

Vlastnosti v PageModel lze označit požadovaným atributem:

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

Další informace najdete v tématu ověřování modelu.

Zpracování požadavků HEAD pomocí Fallback obslužné rutiny OnGet

HEAD žádosti umožňují načíst hlavičky pro konkrétní prostředek. Na rozdíl od GET požadavků HEAD požadavky nevrátí tělo odpovědi.

Obvykle OnHead je obslužná rutina vytvořena a volána pro HEAD požadavky:

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

v ASP.NET Core 2,1 nebo novějších se Razor stránky vrátí k volání OnGet obslužné rutiny, pokud OnHead není definována žádná obslužná rutina. Toto chování je povoleno voláním SetCompatibilityVersion v Startup.ConfigureServices :

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

výchozí šablony generují SetCompatibilityVersion volání v ASP.NET Core 2,1 a 2,2. SetCompatibilityVersion efektivně nastaví Razor možnost stránky AllowMappingHeadRequestsToGetHandler na true .

Místo toho, abyste se rozhodli pro všechna chování pomocí SetCompatibilityVersion , se můžete výslovně vyjádřit ke konkrétnímu chování. Následující kód výslovný v pro povolení HEAD Mapování požadavků na OnGet obslužnou rutinu:

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

XSRF/CSRF a Razor stránky

Nemusíte psát žádný kód pro ověřování proti padělání. Generování a ověření tokenu antipadělání jsou automaticky zahrnuty na Razor stránkách.

Použití rozložení, částečných, šablon a značek pomocníka se Razor stránkami

Stránky fungují se všemi možnostmi Razor modulu zobrazení. Rozložení, částečné typy, šablony, pomocníka značek, _ViewStart. cshtml, _ViewImports. cshtml fungují stejným způsobem jako u konvenčních Razor zobrazení.

Pojďme tuto stránku obstarit tím, že využijete některé z těchto možností.

Přidejte stránku rozložení na stránky/sdílené/_Layout. cshtml:

<!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>

Rozložení:

  • Určuje rozložení jednotlivých stránek (Pokud stránka výslovný mimo rozložení).
  • Importuje struktury HTML, jako jsou JavaScript a StyleSheet.

Další informace najdete na stránce rozložení .

Vlastnost layout je nastavena na stránky/_ViewStart. cshtml:

@{
    Layout = "_Layout";
}

Rozložení se nachází na stránkách nebo ve sdílené složce. Stránky hledají další zobrazení (rozložení, šablony, částečné typy) hierarchicky a začínají ve stejné složce jako aktuální stránka. Rozložení na stránkách nebo ve sdílené složce můžete použít na libovolné Razor stránce ve složce stránky .

Soubor rozložení by měl přejít na stránky nebo do sdílené složky.

Nedoporučujeme umístit soubor rozložení do zobrazení/sdílené složky. Zobrazení/Shared je vzor zobrazení MVC. Razor Stránky mají sloužit k spoléhání se na hierarchii složek, nikoli na konvence cest.

Zobrazení hledání ze Razor stránky obsahuje složku stránky . Rozložení, šablony a částečné typy, které používáte s řadiči MVC a konvenčními Razor zobrazeními, fungují pouze.

Přidejte soubor Pages/_ViewImports. cshtml :

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

@namespace je vysvětleno dále v tomto kurzu. Tato @addTagHelper direktiva přináší předdefinované pomocníky značek všem stránkám ve složce Pages .

V případě @namespace explicitního použití direktivy na stránce:

@page
@namespace RazorPagesIntro.Pages.Customers

@model NameSpaceModel

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

Direktiva nastaví obor názvů pro stránku. @modelDirektiva nemusí zahrnovat obor názvů.

Pokud @namespace je direktiva obsažena v _ViewImports. cshtml, zadaný obor názvů poskytuje předponu pro generovaný obor názvů na stránce, která importuje @namespace direktivu. Zbytek generovaného oboru názvů (část přípony) je relativní cesta oddělená tečkou mezi složkou obsahující _ViewImports. cshtml a složkou obsahující stránku.

Například PageModel třídy 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.

Soubor Pages/_ViewImports. cshtml nastaví následující obor názvů:

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

Vygenerovaný obor názvů pro stránku Pages/Customers/Edit. cshtml Razor je stejný jako PageModel Třída.

@namespacefunguje také s konvenčními Razor zobrazeními.

Soubor zobrazení původní stránky/vytvořit. cshtml :

@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>

Aktualizovaný soubor zobrazení stránky/vytvoření. cshtml :

@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>

Razor Úvodní projekt stránky obsahuje stránky/_ValidationScriptsPartial. cshtml, které se připojí k ověřování na straně klienta.

Další informace o částečných zobrazeních naleznete v tématu Částečná zobrazení v ASP.NET Core .

Generování adresy URL pro stránky

CreateStránka, která se zobrazuje dřív, používá RedirectToPage :

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

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

Aplikace má následující strukturu souborů/složek:

  • /Pages

    • Soubor Index.cshtml

    • /Customers

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

Stránky Pages/Customers/Create.cshtml a Pages/Customers/Edit.cshtml se po úspěchu přesměrují na Pages/Index.cshtml. Řetězec je /Index součástí identifikátoru URI pro přístup k předchozí stránce. Řetězec lze použít ke generování identifikátorů URI na stránce /Index Pages/Index.cshtml. Například:

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

Název stránky je cesta ke stránce z kořenové složky /Pages včetně úvodní / stránky (například /Index ). Předchozí ukázky generování adres URL nabízejí vylepšené možnosti a funkční možnosti před pevným kódováním adresy URL. Generování adres URL používá směrování a může generovat a kódovat parametry podle toho, jak je trasa definovaná v cílové cestě.

Generování adres URL pro stránky podporuje relativní názvy. Následující tabulka ukazuje, která stránka indexu je vybrána s různými RedirectToPage parametry z Pages/Customers/Create.cshtml:

RedirectToPage(x) Stránka
RedirectToPage("/Index") Stránky/index
RedirectToPage("./Index"); Stránky, zákazníci a index
RedirectToPage(".. /Index") Stránky/index
RedirectToPage("Index") Stránky, zákazníci a index

RedirectToPage("Index"), RedirectToPage("./Index") a jsou relativní RedirectToPage("../Index") názvy. Parametr RedirectToPage je zkombinovaný s cestou k aktuální stránce a vypočítá název cílové stránky.

Spojování relativních názvů je užitečné při vytváření lokalit se složitou strukturou. Pokud k propojení mezi stránkami ve složce použijete relativní názvy, můžete tuto složku přejmenovat. Všechny odkazy stále fungují (protože nezahrnují název složky).

Pokud chcete stránku přesměrovat v jiné oblasti,zadejte oblast:

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

Další informace naleznete v tématu Oblasti v ASP.NET Core.

Atribut ViewData

Data lze předat na stránku s atributem ViewDataAttribute. Vlastnosti v kontrolerů nebo modelech stránek s atributem mají uložené a načtené hodnoty Razor [ViewData] z ViewDataDictionary.

V následujícím příkladu obsahuje AboutModel vlastnost Title označenou jako [ViewData] . Vlastnost Title je nastavená na název stránky O službě:

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

    public void OnGet()
    {
    }
}

Na stránce O aplikaci přistupte Title k vlastnosti jako k vlastnosti modelu:

<h1>@Model.Title</h1>

V rozložení se název nač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 na kontroleru. Tato vlastnost ukládá data, dokud se nečtou. Metody Keep Peek a lze použít k prozkoumání dat bez odstranění. TempData je užitečné pro přesměrování, pokud jsou data potřeba pro více než jeden požadavek.

Následující kód nastaví hodnotu Message using 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 using TempData .

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

Model stránky Pages/Customers/Index.cshtml.cs aplikuje [TempData] atribut na vlastnost Message .

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

Další informace najdete v tématu TempData.

Více obslužných rutin na stránku

Následující stránka vygeneruje kód pro dvě obslužné rutiny pomocí asp-page-handler pomocné rutiny značek:

@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>

Formulář v předchozím příkladu má dvě tlačítka pro odeslání, z nichž každé používá k FormActionTagHelper odeslání na jinou adresu URL. Atribut asp-page-handler je doprovodný atribut asp-page k . asp-page-handler generuje adresy URL, které se odešle do jednotlivých metod obslužné rutiny definovaných stránkou. asp-page není zadaný, protože ukázka propojuje s aktuální stránkou.

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

Předchozí kód používá pojmenované metody obslužné rutiny. Pojmenované metody obslužné rutiny se vytvářejí tak, že se vezme text v názvu za a On<HTTP Verb> před Async (pokud existuje). V předchozím příkladu jsou metody stránky OnPost JoinList Async a OnPost JoinListUC Async. Po odebrání OnPost a Async jsou názvy obslužných rutin a JoinList JoinListUC .

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

Pomocí předchozího kódu je cesta URL, do které se odešle OnPostJoinListAsync https://localhost:5001/Customers/CreateFATH?handler=JoinList , . Cesta URL, do které se odešle OnPostJoinListUCAsync , je https://localhost:5001/Customers/CreateFATH?handler=JoinListUC .

Vlastní trasy

Direktivu @page použijte k:

  • Zadejte vlastní trasu na stránku. Například trasu na stránku O službě můžete nastavit na /Some/Other/Path pomocí @page "/Some/Other/Path" .
  • Připojte segmenty k výchozí trase stránky. Například segment "item" je možné přidat na výchozí trasu stránky pomocí @page "item" .
  • Připojte parametry k výchozí trase stránky. Například parametr ID může být vyžadován pro stránku id s @page "{id}" parametrem .

Podporuje se cesta relativní ke kořeni určená tildou ( ) na začátku ~ cesty. Například je @page "~/Some/Other/Path" stejný jako @page "/Some/Other/Path" .

Pokud se vám řetězec dotazu v adrese URL nelíbí, změňte trasu tak, aby se název obslužné rutiny vložil do části adresy ?handler=JoinList URL s cestou. Trasu lze přizpůsobit přidáním šablony trasy uzavřené v dvojitých uvozovkách za @page direktivou .

@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>

Pomocí předchozího kódu je cesta URL, do které se odešle OnPostJoinListAsync https://localhost:5001/Customers/CreateFATH/JoinList , . Cesta URL, do které se odešle OnPostJoinListUCAsync , je https://localhost:5001/Customers/CreateFATH/JoinListUC .

Následující ? příklad handler znamená, že parametr trasy je volitelný.

Konfigurace a nastavení

Ke konfiguraci rozšířených možností použijte rozšiřující metodu AddRazorPagesOptions ve tvůrci MVC:

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

V současné době můžete použít k nastavení kořenového adresáře pro stránky nebo přidat konvence RazorPagesOptions aplikačních modelů pro stránky. V budoucnu tímto způsobem povolíme větší rozšiřitelnost.

Pokud chcete předkompilovat zobrazení, podívejte se Razor na kompilaci zobrazení .

Stáhněte nebo zobrazte vzorový kód.

Viz Začínáme se Razor stránkami, která vychází z tohoto úvodu.

Určení, Razor že stránky jsou v kořenovém adresáři obsahu

Ve výchozím nastavení Razor jsou stránky v kořenovém adresáři /Pages. Přidejte Razor s PagesAtContentRoot do AddMvc a určete, že vaše stránky jsou v kořenovém adresáři obsahu Razor (ContentRootPath)aplikace:

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

Určení, Razor že stránky jsou ve vlastním kořenovém adresáři

Přidejte do AddMvc hodnotu Razor With PagesRoot, která určuje, že vaše stránky jsou v aplikaci ve vlastním kořenovém adresáři Razor (zadejte relativní cestu):

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

Další zdroje informací