【问题标题】:How to create shared form in ASP.NET CORE Razor Pages?如何在 ASP.NET CORE Razor Pages 中创建共享表单?
【发布时间】:2019-04-05 20:58:59
【问题描述】:

我必须在我的页眉中创建一个可重复使用的表单。它应该显示在每一页上。将发送 POST 请求的简单输入和提交按钮。

我知道的选项是部分视图或视图组件。 我检查了有关视图组件的文档,但没有提到它适用于表单。只有InvokeAsync 方法可用于初始化视图。

使用局部视图,可能很难定义其页面模型,我不明白将其 POST 处理程序放在哪里。

我看到的另一个选项,以某种方式直接在_Layout.cshtml 上放置一个表单,但同样,它没有它的页面模型(afaik),

那么什么是创建共享表单的方法,以及应该在哪里处理 POST 请求?

【问题讨论】:

    标签: asp.net razor asp.net-core razor-pages


    【解决方案1】:

    您应该使用视图组件,因为这允许您拥有某种程度独立的模型和视图交互。

    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" />
    

    【讨论】:

    • 我在局部视图中使用了这种方法,因为我不需要重用该表单,但是使用asp-controller 的方法效果很好,这就是我一直缺少的
    • 您可以从请求标头中获取引用而不是隐藏的表单输入,例如Redirect(Request.Headers["Referer"].ToString())?
    • 没有。 1) 不保证此标头存在。它由客户端添加,可以更改或省略。 2)无论如何,它并不总是你需要的。例如,在第一个帖子上,它可能与returnUrl 相同,但如果用户返回该页面以修复错误,那么引荐来源现在就是该页面,而不是用户最初来自的地方。而returnUrl 将在多个帖子中保持一致。
    【解决方案2】:

    如果您想使用PageModel,您可以在继承自PageModelBasePageModel 类中执行此操作,并且您的所有页面都继承自该类。您可以在 BasePageModel 类中使用命名处理程序 (https://www.learnrazorpages.com/razor-pages/handler-methods#named-handler-methods) 来处理表单提交。将表单直接添加到布局中,这需要为您的 BasePageModel 类型提供@model 指令。

    public class BasePageModel : PageModel
    {
        [BindProperty]
        public string SearchString { get; set; }
    
        public void  OnPostBaseSearch()
        {
            // process the search
        }
    }
    

    【讨论】:

    • 这个答案对我来说效果很好。如果您收到错误“表达式树可能不包含动态操作”,则意味着您忘记将其放在 _Layout.chtml 的顶部:@model BasePageModel。
    猜你喜欢
    • 2018-10-29
    • 2021-02-27
    • 2018-10-16
    • 2019-06-03
    • 2018-05-09
    • 2018-06-24
    • 2020-02-03
    • 2019-12-15
    • 2020-11-08
    相关资源
    最近更新 更多