Razor Pages - проблема с частичным просмотром и получением данных из модели

В настоящее время я изучаю ASP.net Core 2.0, в частности страницы Razor. В настоящее время я пытаюсь понять частичные взгляды.

У меня есть страница ViewReport, которая по сути показывает данные для отчета и позволяет пользователю редактировать их. Модель выглядит так:

    namespace ReportControlPanel.Pages
{
    public class ViewReportModel : PageModel
    {
        private readonly ReportControlPanel.Data.MainContext _context;

        public ViewReportModel(ReportControlPanel.Data.MainContext context)
        {
            _context = context;
        }

        [BindProperty]
        public Reports Reports { get; set; }
        [BindProperty]
        public ExecRptModel ExecRptModel { get; set; }

        public async Task<IActionResult> OnGetAsync(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            Reports = await _context.ReportContents
                .SingleOrDefaultAsync(m => m.ID == id);


            if (Reports == null)
            {
                return NotFound();
            }
            return Page();

        }

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

            _context.Attach(Reports).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {

            }

            return RedirectToPage("./Index");
        }
    }
}

Я попытался создать частичное представление ExecRpt, которое показывало бы журналы выполнения отчетов для этого отчета. Модель выглядит так:

namespace ReportControlPanel.Pages
{
    public class ExecRptModel
    {
        private readonly ReportControlPanel.Data.MainContext _context;

        public ExecRptModel(ReportControlPanel.Data.MainContext context)
        {
            _context = context;
        }

        public IList<Logs> Logs { get; set; }

        public async Task OnGetAsync()
        {
            IQueryable<Logs> LogsIQ = from i in _context.vwReportLogs select i;

            Logs = await LogsIQ.ToListAsync();

        }
    }
}

Я визуализирую частичное представление в ViewReport.cshtml следующим образом:

@await Html.PartialAsync("ExecRpt", Model.ExecRptModel)

Мне потребовалось время, чтобы заставить это работать без ошибок.

Затем я перешел к разметке частичного вида. Как только я сделал это, чтобы сгенерировать список в HTML:

@foreach (var item in Model.Logs)
{
    <p>@Html.DisplayFor(i => item.ID)</p> //etc etc
}

Я получаю сбивающую с толку ошибку при отладке.

NullReferenceException: ссылка на объект не установлена ​​на экземпляр объекта.

Ошибка заключается в выделении блока @foreach в моей модели частичного представления.

Теперь я знаю, что модель журналов должна возвращать загрузку данных, потому что она отлично работает, когда не вызывается из частичного представления.

Пожалуйста, может кто-нибудь указать мне в правильном направлении?


person Molenpad    schedule 24.03.2018    source источник
comment
У вас объявлена ​​модель ExecRptModel в вашем представлении? Возможно, вы захотите инициализировать журналы как пустой список при запуске, поскольку загрузка может быть асинхронной.   -  person EzLo    schedule 27.03.2018


Ответы (1)


Ваш класс ExecRptModel содержит метод OnGetAsync (). Это шаблон, используемый классами, производящими PageModel (то есть кодом программной части для Razor Pages). Это недоступно для частичных просмотров. Я уверен, что вы по-прежнему можете вызывать OnGetAsync (), как и любой другой обычный метод, но не ожидайте, что он будет вызываться автоматически при первом рендеринге частичного представления (попробуйте установить точку останова и посмотреть, будет ли выполнен какой-либо код там ). Поэтому я подозреваю, что вы получаете исключение с нулевой ссылкой, потому что журналы никогда не устанавливаются на что-либо, поэтому оно имеет значение null, когда вы пытаетесь перебрать его в представлении.

Я рекомендую перенести логику получения журналов в конструктор ExecRptModel. Или рассмотрите возможность использования View Components, что позволит вы выполняете более сложную логику выборки данных при рендеринге компонента.

person SlyCaptainFlint    schedule 28.05.2018