Razor Pages, обработчик страницы формы не работает с методом GET

У меня есть небольшой проект ASP.NET Core 2.1 Razor Pages. Я делаю простую страницу отображения списка с основными функциями поиска. В моей модели у меня есть 4 обработчика страниц (2 из них добавлены в целях отладки):

        public async Task OnGetAsync()
        {
            Posting = await _context.Postings
                .Include(p => p.ItemDetails).Include(p => p.Owner).ToListAsync();
        }

        public async Task OnPostAsync()
        {
            Posting = await _context.Postings
                .Include(p => p.ItemDetails).Include(p => p.Owner).ToListAsync();
        }

        public async Task<PageResult> OnGetSearchAsync(String search)
        {
            if (String.IsNullOrEmpty(search))
            {
                search = search.Trim();
                Posting = await _context.Postings.Where(p => p.ItemDetails.ItemName.Contains(search)).ToListAsync();
            }
            return Page();
        }

        public async Task<PageResult> OnPostSearchAsync(String search)
        {
            if (!String.IsNullOrEmpty(search))
            {
                search = search.Trim();
                Posting = await _context.Postings.Where(p => p.ItemDetails.ItemName.Contains(search)).ToListAsync();
            }
            return Page();
        }

Когда форма указывает method="post" с asp-page-handler="search", форма вызывает правильный обработчик (OnPostSearchAsync(String search)). Тем не менее, когда форма указывает method="get" с asp-page-handler="search", форма вызывает неправильный обработчик (OnGetAsync()). Это предназначено? Если да, то как я могу вызвать пользовательский обработчик при использовании GET метод? Может быть, использование собственного обработчика не обязательно, но я думаю, что смогу, если захочу.

Вот соответствующий код в .cshtml файл:

<div id="posting_search_bar_container">
    <form method="get" asp-page-handler="search">
        <input type="text" name="search" />
        <input type="submit" value="Ara" />
    </form>
</div>
<div id="posting_list_container">
    @if (Model.Posting != null)
    {
        @foreach (var posting in Model.Posting)
        {
            <partial name="./Partials/_Posting" model="new Pages.Postings.Partials.PostingModel(posting);" />
        }
    }
</div>

Спасибо за прочтение!

1 ответ

Решение

С точки зрения того, почему это происходит, этот ответ должен объяснить, что здесь происходит. По существу, asp-page-handler устанавливает URL-адрес действия, который включает ?handler=search, который затем удаляется браузером для GET-запросов.

С точки зрения обходных путей, я вижу два:

Вариант 1 - настройка маршрутизации

Взятые прямо из документов, вы можете немного изменить директиву страницы в.cshtml, чтобы настроить маршрутизацию:

@page "{handler?}"

Этот параметр указывает, что для данной страницы используйте дополнительный сегмент для указания имени обработчика, а не устанавливайте его в качестве параметра строки запроса. Это означает, что ваши звонки будут меняться, например, с /PageName?handler=handlerName в /PageName/Handler, ? в {handler?} выражение из фрагмента кода просто утверждает, что имя обработчика является необязательным, и поэтому по умолчанию, например, OnGetAsync,

Этот параметр работает, поскольку в браузере больше нет значения строки запроса для мусора, но имя обработчика фиксируется в самом маршруте.

Вариант 2 - использовать скрытый ввод

При отправке формы с помощью GET на определенный URL-адрес действия браузер создает строку запроса из элементов управления, которые находятся внутри формы. Это дает возможность добавить новое скрытое поле ввода в форму:

<form method="get">
    <input type="hidden" name="handler" value="search" />
    <input type="text" name="search" />
    <input type="submit" value="Ara" />
</form>

Здесь я удалил asp-page-handler и добавил скрытый ввод, который в итоге установит значение строки запроса handler в search, который создает строку запроса, которая будет соответствовать OnGetSearchAsync в вашем примере.

Другие вопросы по тегам