Передать модель в представление PartialAsyn c (Razor, MVC) - PullRequest
0 голосов
/ 07 января 2020

У меня есть AccountController.cs со следующим действием:

[HttpGet]
[AllowAnonymous]
public IActionResult Register()
 {
   ViewBag.Registration = GetRegistration();
   return View();
 }

ViewBag.Registration содержит 2 элемента, и все в порядке.

Тогда Я получил Registration.cs html представление:

@model Registration <!-- this model I'm using for other form -->   
@{
    Layout = "_Layout";
}    
<!-- some code -->

@await Html.PartialAsync("AllRegistered")

и AllRegistered.cs html, где данные из ViewBag.Registration должно отображаться:

@model IEnumerable<Registration>

<table>
    <tr>
        <th>@Html.DisplayNameFor(m => m.Email)</th>
        <th>@Html.DisplayNameFor(m => m.City)</th>
    </tr>

    @if (Model != null && Model.Count() != 0)
    {
        @foreach (Registration registration in Model)
        {
            <tr>
                <th>@Html.DisplayFor(m => registration.Email)</th>
                <th>@Html.DisplayFor(m => registration.City)</th>
            </tr>
        }
     }
</table>

Но в поле зрения ничего не генерируется, модель, я думаю, пуста.

Ответы [ 2 ]

2 голосов
/ 07 января 2020

Метод PartialAsyn c содержит перегрузку, включающую модель:

Html.PartialAsync(string partialViewName, TModel model)

В этот помощник следует включить IEnumerable<Registration> (модель частичного представления).

Если GetRegistrations () возвращает IEnumerable, вы должны определить частичное представление следующим образом:

@await Html.PartialAsync("AllRegistered", (List<Registration>)ViewBag.Registration)

1 голос
/ 07 января 2020

Хотя ответ Натана совершенно правильный, было бы более уместным, чтобы это было компонентом представления. Тот факт, что вы хотите отобразить все регистрации, является подробным видом, который не имеет никакого отношения к цели этого действия. Таким образом, для того, чтобы действие отвечало за извлечение данных, требуется, чтобы оно обладало знаниями, в которых оно не нуждается и не должно иметь.

Вместо этого добавьте такой класс:

public class AllRegistrationsViewComponent : ViewComponent
{
    private readonly RegistrationsService _service;

    public AllRegistrationsViewComponent(RegistrationService service)
    {
        _service = service;
    }

    public async Task<IViewComponentResult> InvokeAsync()
    {
        // logic behind `GetRegistrations()` here
        return View(registrations);
    }
}

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

Затем создайте представление Views/Components/AllRegistrations/Default.cshtml с помощью:

@model IEnumerable<Registration>

<table>
    <tr>
        <th>@Html.DisplayNameFor(m => m.Email)</th>
        <th>@Html.DisplayNameFor(m => m.City)</th>
    </tr>

    @if (Model != null && Model.Count() != 0)
    {
        @foreach (Registration registration in Model)
        {
            <tr>
                <th>@Html.DisplayFor(m => registration.Email)</th>
                <th>@Html.DisplayFor(m => registration.City)</th>
            </tr>
        }
     }
</table>

Часть пути AllRegistrations основана на имени просмотреть компонент без части ViewComponent, поэтому, если вы называете его по-другому, настройте его здесь.

Наконец, на ваш взгляд:

@await Component.InvokeAsync("AllRegistrations")

Тогда ваше действие может быть просто сфокусировано по своему фактическому назначению:

[HttpGet]
[AllowAnonymous]
public IActionResult Register()
{
    return View();
}
...