Вы должны использовать компонент представления, поскольку это позволяет вам иметь несколько автономную модель и взаимодействие представления.
public class SharedFormViewComponent : ViewComponent
{
public Task<IViewComponentResult> InvokeAsync() =>
Task.FromResult(View(new SharedFormViewModel()));
}
Затем введите HTML-код вашей формы в Views\Shared\Components\SharedForm\Default.cshtml
. Для действия вашей формы вам нужно будет указать маршрут. Подробнее об этом в с. Затем для отображения вашей формы:
@await Component.InvokeAsync("SharedForm")
Теперь, как вы уже заметили, компоненты представления нельзя публиковать. Это не проблема «не поддерживающих форм»; они буквально не являются частью конвейера запросов и поэтому не могут отвечать на запросы, такие как POST. Вам понадобится отдельное действие, которое будет обрабатывать POST на некотором контроллере. Затем в теге формы вашего компонента:
<form asp-action="SharedFormHandlerAction" asp-controller="Foo" asp-area="" method="post">
Атрибут asp-area
должен быть предоставлен на случай, если он используется в контексте различных областей.
Вам также понадобится «обратный URL». Это будет URL-адрес текущей страницы, поэтому после того, как пользователь успешно отправит форму, он вернется на страницу, с которой отправил ее. Вы можете достичь этого, добавив скрытый ввод в форму:
<input type="hidden" name="returnUrl" value="@(Context.Request.Query["returnUrl"].FirstOrDefault() ?? (Context.Request.Path + Context.Request.QueryString))" />
В этом случае ваш обработчик должен принимать такой параметр, как string returnUrl = null
, и в случае успеха вы должны выполнить:
return !string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl)
? Redirect(returnUrl)
: RedirectToAction("SomeDefaultAction");
Что немного сложнее, так это обработка ошибок валидации. Поскольку вы публикуете другое действие, вы не можете вернуть предыдущее представление, в котором находился пользователь, чтобы показать ошибки валидации в поле from в макете или что-либо еще. Вместо этого вам понадобится представление, специфичное для этого действия обработчика, которое будет просто вашей общей формой. Вы можете использовать представление для вашего компонента представления здесь как частичное:
<partial name="~\Views\Shared\Components\SharedForm\Default.cshtml" />