Поделиться через


Страницы, маршрутизация и макеты

Подсказка

Это фрагмент из электронной книги для разработчиков ASP NET веб-формы для Azure, Blazor доступных в документации .NET или в виде бесплатного скачиваемого PDF-файла, который можно читать в автономном режиме.

Blazor-for-ASP-NET-Web-Forms-Developers eBook cover эскиз.

Приложения на основе веб-форм ASP.NET состоят из страниц, определяющихся в файлах .aspx. Адрес каждой страницы основан на его физическом пути к файлу в проекте. Когда браузер отправляет запрос на страницу, содержимое страницы динамически генерируется на сервере. Отрисовка учитывает HTML-разметку страницы и ее серверные элементы управления.

В Blazorприложении каждая страница — это компонент, который обычно определяется в razor-файле с одним или несколькими указанными маршрутами. Маршрутизация в основном выполняется на стороне клиента без участия конкретного запроса сервера. В браузере сначала выполняется запрос к корневому адресу приложения. Затем корневой Router компонент в Blazor приложении обрабатывает перехват запросов навигации и перенаправляет их в правильный компонент.

Blazor также поддерживает глубокие ссылки. Глубокая ссылка возникает, когда браузер выполняет запрос к определенному маршруту, отличному от корня приложения. Запросы на глубокие ссылки, отправленные на сервер, перенаправляются в приложение Blazor, которое затем отправляет запрос клиентской стороне к правильному компоненту.

Простая страница в веб-формах ASP.NET может содержать следующую разметку:

Name.aspx

<%@ Page Title="Name" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Name.aspx.cs" Inherits="WebApplication1.Name" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <div>
        What is your name?<br />
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="Submit" OnClick="Button1_Click" />
    </div>
    <div>
        <asp:Literal ID="Literal1" runat="server" />
    </div>
</asp:Content>

Name.aspx.cs

public partial class Name : System.Web.UI.Page
{
    protected void Button1_Click1(object sender, EventArgs e)
    {
        Literal1.Text = "Hello " + TextBox1.Text;
    }
}

Эквивалентная страница в Blazor приложении будет выглядеть следующим образом:

Name.razor

@page "/Name"
@layout MainLayout

<div>
    What is your name?<br />
    <input @bind="text" />
    <button @onclick="OnClick">Submit</button>
</div>
<div>
    @if (name != null)
    {
        @:Hello @name
    }
</div>

@code {
    string text;
    string name;

    void OnClick() {
        name = text;
    }
}

Создание страниц

Чтобы создать страницу в Blazor, создайте компонент и добавьте директиву Razor @page, чтобы указать маршрут для этого компонента. Директива @page принимает один параметр, который является шаблоном маршрута для добавления в этот компонент.

@page "/counter"

Требуется параметр шаблона маршрута. В отличие от ASP.NET веб-форм, маршрут к Blazor компоненту не выводится из его расположения файла (хотя он может быть добавлен в будущем).

Синтаксис шаблона маршрута — это тот же базовый синтаксис, который используется для маршрутизации в ASP.NET веб-формах. Параметры маршрута указываются в шаблоне с помощью фигурных скобок. Blazor привязывает значения маршрута к параметрам компонента с тем же именем (без учета регистра).

@page "/product/{id}"

<h1>Product @Id</h1>

@code {
    [Parameter]
    public string Id { get; set; }
}

Кроме того, можно указать ограничения для значения параметра маршрута. Например, чтобы ограничить идентификатор продукта следующим int:

@page "/product/{id:int}"

<h1>Product @Id</h1>

@code {
    [Parameter]
    public int Id { get; set; }
}

Полный список ограничений маршрута, поддерживаемых Blazor, см. в разделе «Ограничения маршрута».

Компонент маршрутизатора

Маршрутизация в Blazor выполняется компонентом Router. Компонент Router обычно используется в корневом компоненте приложения (App.razor).

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

Компонент Router обнаруживает маршрутизируемые компоненты в указанном AppAssembly и, при наличии, в указанном AdditionalAssemblies. При навигации браузера Router перехватывает переход и отрисовывает содержимое параметра Found с извлеченным значением RouteData, если маршрут совпадает с адресом, в противном случае Router отрисовывает содержимое параметра NotFound.

Компонент RouteView выполняет рендеринг сопоставленного компонента, указанного в RouteData, вместе с его макетом, если он есть. Если соответствующий компонент не имеет макета, используется необязательный параметр DefaultLayout .

Компонент LayoutView отображает дочернее содержимое в заданной компоновке. Более подробно рассмотрим макеты в этой главе.

В веб-формах ASP.NET вы вызываете навигацию на другую страницу, отправляя в браузер ответ с перенаправлением. Рассмотрим пример.

protected void NavigateButton_Click(object sender, EventArgs e)
{
    Response.Redirect("Counter");
}

Возврат ответа перенаправления обычно невозможен Blazor. Blazor не использует модель ответа на запрос. Однако вы можете активировать навигацию в браузере напрямую, как можно с помощью JavaScript.

Blazor NavigationManager предоставляет службу, которую можно использовать для:

  • Получение текущего адреса браузера
  • Получение базового адреса
  • Триггеры навигации
  • Получение уведомлений при изменении адреса

Чтобы перейти к другому NavigateTo адресу, используйте метод:

@page "/"
@inject NavigationManager NavigationManager

<button @onclick="Navigate">Navigate</button>

@code {
    void Navigate() {
        NavigationManager.NavigateTo("counter");
    }
}

Описание всех участников NavigationManager можно найти в разделе URI и вспомогательных средств управления состоянием навигации.

Базовые URL-адреса

Если ваше приложение Blazor развертывается по базовому пути, необходимо указать базовый URL-адрес в метаданных страницы с помощью тега <base>, чтобы маршрутизация работала правильно. Если хост-страница приложения обрабатывается сервером с помощью Razor, то можно использовать синтаксис ~/ для указания базового адреса приложения. Если на хост-странице имеется статический HTML-код, необходимо явно указать базовый URL-адрес.

<base href="~/" />

Макет страницы

Макет страницы в Web Forms ASP.NET управляется мастер-страницами. Главные страницы определяют шаблон с одним или несколькими заполнителями контента, которые затем могут быть предоставлены отдельными страницами. Главные страницы определяются в файлах .master и начинаются с директивы. Содержимое master-файлов закодировано как страница .aspx , но с добавлением <asp:ContentPlaceHolder> элементов управления, чтобы пометить, где страницы могут предоставлять содержимое.

Site.master

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WebApplication1.SiteMaster" %>

<!DOCTYPE html>
<html lang="en">
<head runat="server">
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title><%: Page.Title %> - My ASP.NET Application</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
</head>
<body>
    <form runat="server">
        <div class="container body-content">
            <asp:ContentPlaceHolder ID="MainContent" runat="server">
            </asp:ContentPlaceHolder>
            <hr />
            <footer>
                <p>&copy; <%: DateTime.Now.Year %> - My ASP.NET Application</p>
            </footer>
        </div>
    </form>
</body>
</html>

В Blazor вы оформляете страницу с использованием компонентов макета. Компоненты макета наследуются от LayoutComponentBase, который определяет одно свойство Body типа RenderFragment, которое можно использовать для отрисовки содержимого страницы.

MainLayout.razor

@inherits LayoutComponentBase
<h1>Main layout</h1>
<div>
    @Body
</div>

При отрисовке страницы с макетом, страница встраивается в содержимое указанного макета в месте, где макет выводит свое свойство Body.

Чтобы применить макет к странице, используйте директиву @layout :

@layout MainLayout

Макет для всех компонентов в папке и вложенных папках можно указать с помощью файла _Imports.razor . Вы также можете указать макет по умолчанию для всех страниц с помощью компонента Маршрутизатора.

Страницы-шаблоны могут определять несколько заполнителей контента, но в Blazor каждый макет имеет только одно свойство Body. Это ограничение компонентов макета Blazor , надеюсь, будет решено в будущем выпуске.

Основные страницы в веб-формах ASP.NET можно вкладывать. То есть эталонная страница может также использовать главную страницу. Компоненты макета в Blazor также могут быть вложены. Компонент макета можно применить к компоненту макета. Содержимое внутреннего макета будет отображаться в внешнем макете.

ChildLayout.razor

@layout MainLayout
<h2>Child layout</h2>
<div>
    @Body
</div>

Index.razor

@page "/"
@layout ChildLayout
<p>I'm in a nested layout!</p>

Затем результатом отрисовки страницы будет следующее:

<h1>Main layout</h1>
<div>
    <h2>Child layout</h2>
    <div>
        <p>I'm in a nested layout!</p>
    </div>
</div>

Макеты в Blazor обычно не определяют корневые HTML-элементы для страницы (<html>, <body>, <head>, и т. д.). Корневые элементы HTML вместо этого определяются на главной странице приложения Blazor, которая используется для отображения начального HTML-содержимого для приложения (см. Bootstrap Blazor). На странице хоста можно отобразить несколько корневых компонентов приложения с окружающей их разметкой.

Компоненты в Blazor, включая страницы, не могут отображать <script> теги. Это ограничение отрисовки существует, так как <script> теги загружаются один раз, а затем не могут быть изменены. Непредвиденное поведение может произойти, если вы пытаетесь динамически отобразить теги с помощью синтаксиса Razor. Вместо этого все <script> теги должны быть добавлены на страницу хоста приложения.