Ошибка при присвоении значения ViewData в PageFilter

Я работаю над PageFilter, который я могу вызывать на каждой странице, чтобы получить данные для моей страницы _Layout:

public class GetEventFilter : IAsyncPageFilter
{
    private readonly DBContext _context;

    public GetEventFilter(DBContext context)
    {
        _context = context;
    }

    public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
    {

        if (context.HandlerInstance is PageModel result)
        {

            //result.Response.StatusCode = 400;
            context.Result = result.Page();

            DateTime dt = DateTime.Now;

            var thisEvent = await _context.Events.Include(x => x.AdminCompany).Where(x => x.Domain == context.HttpContext.Request.Host.Host && x.Status == 1 && x.ActiveFromDateTime <= dt && x.ActiveToDateTime > dt).OrderBy(x => x.ActiveFromDateTime).FirstOrDefaultAsync();

            if (thisEvent != null)
            {
                if (thisEvent.Logo != null)
                {
                    result.ViewData["Site_EventLogo"] = "/data/" + thisEvent.AdminCompany.Id + "/" + thisEvent.Id + "/media/" + thisEvent.Logo;
                }
                else
                {
                    result.ViewData["Site_EventLogo"] = "/data/" + thisEvent.AdminCompany.Id + "/_system/media/" + thisEvent.AdminCompany.Logo;
                }
                result.ViewData["Site_EventId"] = thisEvent.Id.ToString();
                result.ViewData["Site_EventName"] = thisEvent.Name;
                result.ViewData["Site_EventDomain"] = thisEvent.Domain;
                result.ViewData["Site_CompanyId"] = thisEvent.AdminCompany.Id;
                result.ViewData["Site_CompanyName"] = thisEvent.AdminCompany.Name;
                result.ViewData["Site_CompanyAddress"] = thisEvent.AdminCompany.Address;
                result.ViewData["Site_CompanyPostalCode"] = thisEvent.AdminCompany.PostalCode;
                result.ViewData["Site_CompanyCity"] = thisEvent.AdminCompany.City;
                result.ViewData["Site_CompanyPhone"] = thisEvent.AdminCompany.Phone;
                result.ViewData["Site_CompanyEmail"] = thisEvent.AdminCompany.Email;
                //await next.Invoke();
            }
            else
            {
                context.HttpContext.Response.Redirect("/error/404");
            }

        }

    }

    public async Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context) => await Task.CompletedTask;

}

Моя проблема в том, что когда я присваиваю значения объекту ViewData, я получаю NullReferenceException: Object reference not set to an instance of an object.-ошибку.

Как я могу это исправить? Я знаю, что такое NullReferenceException, я просто не знаю, почему я получаю его в этом примере.


person Mads    schedule 12.07.2019    source источник
comment
Возможный дубликат Что такое исключение NullReferenceException и как мне исправить?   -  person Rahul Sharma    schedule 12.07.2019
comment
Спасибо, @RahulSharma. Я знаю, что такое NullReferenceException, я просто не знаю, почему я получаю его в этом примере.   -  person Mads    schedule 12.07.2019
comment
Эта ссылка содержит объяснение вашего случая: stackoverflow.com/questions/53984956/   -  person Rahul Sharma    schedule 12.07.2019
comment
Я тоже это нашел, и, кажется, это меня кое-что привело. Проблема в том, что когда я это реализую, код в обработчике не выполняется / не возвращается в представление? См. Обновленный вопрос.   -  person Mads    schedule 12.07.2019
comment
В вашем вопросе вы вызываете свою задачу: await next.Invoke();. Я вижу, это закомментировано   -  person Rahul Sharma    schedule 12.07.2019
comment
да. В противном случае я получил ошибку If an IAsyncPageFilter provides a result value by setting the Result property of PageHandlerExecutingContext to a non-null value, then it cannot call the next filter by invoking PageHandlerExecutionDelegate. Закомментируйте context.Result = result.Page();и включив await next.Invoke(); сделал это. Спасибо! Пожалуйста, отправьте ответ.   -  person Mads    schedule 12.07.2019
comment
Вы добавили точку останова и проверили, что / что равно нулю?   -  person Ason    schedule 13.07.2019


Ответы (2)


После обсуждения этой проблемы первым шагом было выяснить, почему PageResult всегда возвращает null. Ответ на этот вопрос был найден здесь. После решения первой проблемы было обнаружено, что при вызове await next.Invoke(); возникла следующая ошибка: If an IAsyncPageFilter provides a result value by setting the Result property of PageHandlerExecutingContext to a non-null value, then it cannot call the next filter by invoking PageHandlerExecutionDelegate.

Чтобы устранить эту ошибку, присвоение результата контекста: context.Result = result.Page(); было удалено, а затем задача была вызвана снова, что разрешило всю проблему.

person Rahul Sharma    schedule 14.07.2019
comment
Спасибо, Рахул. Небольшой побочный вопрос, если вы не возражаете: является ли PageFilter «правильным» способом получить то, что я хочу в данном случае? Раньше я смотрел на BasePageModel, но не смог сохранить ViewData. Может быть, это просто название «Фильтр» заставляет меня думать о другом. - person Mads; 15.07.2019
comment
@Mads Способ PageFilter в вашем случае правильный, так как вы обращаетесь к HttpContext. Filters отличаются от Middleware тем, что они предоставляют доступ к HttpContext. Одна из вещей, которую вы, возможно, захотите сделать в фильтре, - это получить данные из внешнего ресурса (базы данных, веб-службы и т. Д.), А затем использовать их в PageModel или ViewData, что вы и делаете. - person Rahul Sharma; 15.07.2019

ViewData - это словарь, а это значит, что для вставки нового элемента вам нужно будет использовать метод Add:

result.ViewData.Add("Site_EventLogo", "/data/" + thisEvent.AdminCompany.Id + "/" + thisEvent.Id + "/media/" + thisEvent.Logo);
person Bart van der Drift    schedule 12.07.2019