ASP.NET Core 中的显示和编辑器模板

发布时间 2023-08-08 15:09:38作者: 大西瓜3721

显示模板和编辑器模板指定了自定义类型的用户界面布局。 考虑下列 Address 模型:

C#
public class Address
{
    public int Id { get; set; }
    public string FirstName { get; set; } = null!;
    public string MiddleName { get; set; } = null!;
    public string LastName { get; set; } = null!;
    public string Street { get; set; } = null!;
    public string City { get; set; } = null!;
    public string State { get; set; } = null!;
    public string Zipcode { get; set; } = null!;
}

设置 Address 模型基架的项目按以下形式显示 Address

模型的默认基架布局视图

网站可使用显示模板以标准格式显示 Address

使用地址模板的默认基架布局的视图

显示模板和编辑器模板还可以减少代码重复和维护成本。 请考虑一个在 20 个不同页面上显示 Address 模型的网站。 如果模型 Address 发生更改,则需要更新全部 20 个页面。 如果对 Address 模型使用显示模板,则只需更新显示模板。 例如,Address 模型可能会更新显示国家或地区。

标记帮助程序提供了另一种方法,使服务器端代码可在 Razor 文件中参与 HTML 元素的创建和呈现。 有关详细信息,请参阅标记帮助程序与 HTML 帮助程序的比较

显示模板

DisplayTemplates 可自定义模型字段的显示,或者在模型值与其显示之间创建一个抽象层。

DisplayTemplate 是 DisplayTemplates 文件夹中的 Razor 文件:

  • 对于 Razor Pages 应用,则在 Pages/Shared/DisplayTemplates 文件夹中。
  • 对于 MVC 应用,则在 Views/Shared/DisplayTemplates 文件夹或 Views/ControllerName/DisplayTemplates 文件夹中。 Views/Shared/DisplayTemplates 中的显示模板供应用中的所有控制器使用。 Views/ControllerName/DisplayTemplates 文件夹中的显示模板仅由 ControllerName 控制器解析。

按照约定,DisplayTemplate 文件以要显示的类型命名。 此示例中使用的 Address.cshtml 模板:

CSHTML
@model Address

<dl>
    <dd>@Model.FirstName @Model.MiddleName @Model.LastName</dd>
    <dd>@Model.Street</dd>
    <dd>@Model.City @Model.State @Model.Zipcode</dd>
</dl>

视图引擎会自动在 DisplayTemplates 文件夹中查找与类型名称匹配的文件。 如果找不到匹配的模板,它将回退到内置模板。

以下代码显示了已搭建基架的项目的“详细信息”视图:

CSHTML
@page
@model WebAddress.Pages.Adr.DetailsModel

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Address</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Address.FirstName)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Address.FirstName)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Address.MiddleName)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Address.MiddleName)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Address.LastName)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Address.LastName)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Address.Street)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Address.Street)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Address.City)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Address.City)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Address.State)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Address.State)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Address.Zipcode)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Address.Zipcode)
        </dd>
    </dl>
</div>
<div>
    <a asp-page="./Edit" asp-route-id="@Model.Address?.Id">Edit</a> |
    <a asp-page="./Index">Back to List</a>
</div>

以下代码显示了使用地址显示模板的“详细信息”视图:

CSHTML
@page
@model WebAddress.Pages.Adr2.DetailsModel

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Address DM</h4>
    <hr />
    <dl class="row">
        <dd class="col-sm-10">
           @Html.DisplayFor(model => model.Address)
        </dd>
    </dl>
</div>
<div>
    <a asp-page="./Edit" asp-route-id="@Model.Address?.Id">Edit</a> |
    <a asp-page="./Index">Back to List</a>
</div>

若要引用名称与类型名称不匹配的模板,请在 DisplayFor 方法中使用 templateName 参数。 例如,以下标记使用 AddressShort 模板显示 Address 模型:

CSHTML
@page
@model WebAddress.Pages.Adr2.DetailsCCModel

@{
    ViewData["Title"] = "Details Short";
}

<h1>Details Short</h1>

<div>
    <h4>Address Short</h4>
    <hr />
    <dl class="row">
        <dd class="col-sm-10">
           @Html.DisplayFor(model => model.Address,"AddressShort")
        </dd>
    </dl>
</div>

使用所提供的公开 additionalViewData 参数的 DisplayFor 重载之一来传递额外视图数据,这些数据合并到为模板创建的视图数据字典实例中。

编辑器模板

编辑或更新模型时,会在窗体控件中使用编辑器模板。

EditorTemplate 是 EditorTemplates 文件夹中的 Razor 文件:

  • 对于 Razor Pages 应用,则在 Pages/Shared/EditorTemplates 文件夹中。
  • 对于 MVC 应用,则在 Views/Shared/EditorTemplates 文件夹或 Views/ControllerName/EditorTemplates 文件夹中。

以下标记显示了示例中使用的 Pages/Shared/EditorTemplates/Address.cshtml

CSHTML
@model Address

<dl>
    <dd>    Name:
        <input asp-for="FirstName" /> <input asp-for="MiddleName" /> <input asp-for="LastName" /> 
    </dd>
        <dd>    Street:
        <input asp-for="Street" /> 
    </dd>

        <dd>    city/state/zip:
        <input asp-for="City" /> <input asp-for="State" /> <input asp-for="Zipcode" /> 
    </dd>

</dl>

以下标记显示了使用 Pages/Shared/EditorTemplates/Address.cshtml 模板的 Edit.cshtml 页面:

CSHTML
@page
@model WebAddress.Pages.Adr.EditModel

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

<h1>Edit</h1>

<h4>Address</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="Address.Id" />
             @Html.EditorFor(model => model.Address)
            <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");}
}