我必须在页面标题中创建一个可重用的表单。它应该显示在每一页上。简单的输入和提交按钮将发送POST请求。
我知道的选项是局部视图或视图组件。
我查看了有关视图组件的文档,但没有提及它可与表单一起使用。只有InvokeAsync
方法可用于初始化视图。
使用局部视图,可能很难定义其页面模型,并且我不知道将其POST处理程序放在哪里。
我看到了另一个选择,它以某种方式直接将表单放置在_Layout.cshtml
上,但是同样,它没有页面模型(afaik),
那么创建共享表单的方法是什么,应该在哪里处理POST请求?
答案 0 :(得分:4)
您应该使用视图组件,因为这使您可以拥有一个完全独立的模型和视图交互。
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" />
答案 1 :(得分:1)
如果您想使用new
,则可以在PageModel
继承的BasePageModel
类中使用,并且您的所有页面都继承。您可以在PageModel
类中使用命名处理程序(https://www.learnrazorpages.com/razor-pages/handler-methods#named-handler-methods)处理表单提交。将表单直接添加到Layout,您的BasePageModel类型将需要一个BasePageModel
指令。
@model