Как использовать DisplayTemplates в ASP.Net Core Razor Pages с наследованием модели? - PullRequest
1 голос
/ 03 октября 2019

Попытка заставить DisplayTemplates в ASP.Net Core 2.2 работать с классами, которые наследуются от базового класса, подобного этому вопросу Как обрабатывать модель сущностей с наследованием в представлении?

Principal DisplayTemplate используется для всех элементов в списке, что мне не хватает?

PageModel

public class IndexModel : PageModel
{
    public List<Principal> Principals { get; set; } = new List<Principal>();

    public void OnGet()
    {
        Principals.Add(new Principal { Id = 1, Name = "Principal 1" });
        Principals.Add(new UserPrincipal { Id = 1, Name = "User 1", Age = 30 });
        Principals.Add(new GroupPrincipal { Id = 1, Name = "Group 1", Members = 5 });
        Principals.Add(new UserPrincipal { Id = 1, Name = "User 2", Age = 40 });
        Principals.Add(new GroupPrincipal { Id = 1, Name = "Group 2", Members = 3 });
    }
}

public class Principal
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class UserPrincipal : Principal
{
    public int Age { get; set; }
}

public class GroupPrincipal : Principal
{
    public int Members { get; set; }
}

RazorPage

@page
@model IndexModel

@foreach(var principal in Model.Principals)
{
    @Html.DisplayFor(p => principal)
}

~ / Pages / Shared / DisplayTemplates / Principal.cshtml

@model Principal
<div>
    <h4>Principal</h4>
    @Model.Name
</div>

~ / Pages / Shared / DisplayTemplates / UserPrincipal.cshtml

@model UserPrincipal
<div>
    <h4>User</h4>
    @Model.Name, Age @Model.Age
</div>

~ / Pages / Shared / DisplayTemplates / GroupPrincipal.cshtml

@model GroupPrincipal
<div>
    <h4>Group</h4>
    @Model.Name, Members @Model.Members
</div>

1 Ответ

0 голосов
/ 04 октября 2019

Причина

Основной шаблон отображения используется для всех элементов списка,

Это потому, что выражение в @Html.DisplayFor(expression) не будет выполнено вообще. Вместо этого они статически анализируются .

Например, если у нас есть выражение m.a.b.c, где a равно null во время выполнения, @Html.DisplayFor(m => m.a.b.c) все еще может узнать шаблон для c.

Поскольку вы объявляете Principals типом List<Principal>, даже если вы удерживаете Model.Principals Hold UserPrincipal или GroupPrincipal во время выполнения , "парсер" все еще обрабатывает principal как базовый Principal тип: они не проверяют реальный тип instance . Они просто статически анализируют тип .

Как исправить

Передавайте имя шаблона при вызове Html.DisplayFor(), чтобы Html Helper знал реальный шаблон, который вы хотите использовать:

@page
@model IndexModel

@foreach (var principal in Model.Principals)
{
    @Html.DisplayFor(p => principal, <b>principal.GetType().Name</b>)
}

Демо

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...