【问题标题】:Why are my Razor Pages forms not posting to the correct handlers?为什么我的 Razor Pages 表单没有发布到正确的处理程序?
【发布时间】:2020-04-10 10:39:13
【问题描述】:

我正在使用 ASP.NET Core 3.0 构建一个 Web 应用程序。我有一个名为Article 的模型。我的应用程序的两个部分都存在问题,其中编辑和删除文章都没有调用正确的 POST 方法处理程序。

我的Article类在命名空间Models中定义如下:

Models/Articles.cs

public class Article
{
  public int Id { get; set; }

  [Required]
  [StringLength(32)]
  public string Title { get; set; }

  [StringLength(512)]
  public string Description { get; set; }

  public string Content { get; set; }
}

编辑

我有一个名为_Editor.cshtml 的共享局部视图。定义如下:

页面/文章/_Editor.cshtml

@model Models.Article

<div class="form-group">
    <label asp-for="Title" class="control-label col-xs-4 col-md-2"></label>
    <input asp-for="Title" class="form-control col-xs-8 col-md-10" />
    <span asp-validation-for="Title" class="text-danger col"></span>
</div>

<div class="form-group">
    <label asp-for="Description" class="control-label col-xs-4 col-md-2"></label>
    <textarea asp-for="Description" class="form-control col-xs-8 col-md-10" style="height:4em"></textarea>
    <span asp-validation-for="Description" class="text-danger col"></span>
</div>

<hr />

<div class="form-group">
    <label asp-for="Content" class="control-label col-xs-4 col-md-2"></label>
    <textarea asp-for="Content" class="form-control col-xs-8 col-md-10" style="height:16em"></textarea>
    <span asp-validation-for="Content" class="text-danger col"></span>
</div>

我在Edit.cshtmlCreate.cshtml 文件中使用这个局部视图,如下所示:

页面/文章/Edit.cshtml

@page
@model Pages.Articles.EditModel

<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <input type="hidden" asp-for="Article.Id" />
    <partial name="_Editor" model="Model.Article" />

    <div class="form-group">
        <input type="submit" value="Save" class="btn btn-primary" />
    </div>
</div>

</form>

页面/文章/Create.cshtml

@page
@model Pages.Articles.CreateModel

<form method="post">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <partial name="_Editor" model="Model.Article" />

    <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" />
    </div>
</form>

这两个 Razor 页面都有标准的脚手架代码隐藏 (.cshtml.cs) 文件。 创建页面运行成功,但编辑页面实际上并没有保存编辑内容。


删除

在我的View.cshtml Razor 页面上,我想要一个可以在整个项目的其他页面中使用的文章删除对话框。我为此使用了Delete.cshtml 部分视图。其代码如下:

页面/文章/Delete.cshtml

@model Models.Article

<div class="modal" tabindex="-1" role="dialog" id="deletionModal">
    <form id="deletionModalForm" asp-page="Articles/Delete" method="post">
        <div class="modal-dialog modal-dialog-centered" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Delete Article</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <p>Are you sure you want to delete the article "@Model.Title"?</p>

                    <input type="hidden" asp-for="@Model.Id" />
                </div>
                <div class="modal-footer">
                    <button type="submit" class="btn btn-danger">Delete</button>
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                </div>
            </div>
        </div>
    </form>
</div>

View.cshtmlRazor页面中引用如下:

页面/文章/View.cshtml

@page
@model Comprehension.Pages.Articles.ViewModel

<partial name="Delete" model="Model.Article" />

<div class="row mb-4">
    <h2 class="col">@Model.Article.Title</h2>
    <p class="col-auto">
        <a asp-page="./Edit" asp-route-id="@Model.Article.Id" class="text-primary">Edit</a>
    </p>
    <p class="col-auto">
        <a class="text-danger" data-toggle="modal" data-target="#deletionModal">Delete</a>
    </p>
</div>

这两个页​​面具有以通常方式构建的代码隐藏 (.cshtml.cs) 文件。 每当在Delete.cshtml 中按下提交按钮时,都会调用View.cshtml.cs 中的OnPost 方法,而不是Delete.cshtml.cs 中的OnPost 方法。

我尝试将@page 添加到Delete.cshtml 无济于事。我也按照@Xing Zou 的建议尝试了所有方法。


在我看来,这两个问题源于同一个错误,但我不确定那个错误是什么。任何帮助将不胜感激。

关于上下文,这是我的项目结构的屏幕截图。

【问题讨论】:

    标签: c# asp.net-core razor partial-views razor-pages


    【解决方案1】:

    我的理解是,你先点击一个按钮(名为Delete),然后弹出一个共享对话框,你可以在对话框中看到Title确认。最后点击对话框中的Delete按钮调用删除文章的实际帖子处理程序。

    下面是我的简单演示:

    1._Delete.cshtml

    为模型添加 id 并添加 &lt;form&gt; 标签以提交到您的删除处理程序

    @model Models.Article
    <div class="modal" tabindex="-1" role="dialog" id="myModal">
        <form id="myForm" method="post">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">Delete Article</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <p>Are you sure you want to delete the article "@Model.Title"?</p>
    
                        @*Pass current article ID*@
                        <input type="hidden" asp-for="@Model.Id" />
                    </div>
                    <div class="modal-footer">
                        <button type="submit" asp-page="Articles/Delete"  class="btn btn-danger">Delete</button>
                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                    </div>
                </div>
            </div>
         </form>
    </div>
    

    2.Index.cshtml:

    <partial name="_Delete" model="@Model.Article" />
    <button type="button" class="btn btn-primary myButton" data-toggle="modal" data-target="#myModal">
        Delete
    </button>
    

    3.Pages/Articles/Delete.cshtml(Delete.cshtml.cs) 剃刀页面

    public async Task<IActionResult> OnPostAsync(int? id)
    {
     //your delete logic
    }
    

    2019 年 12 月 24 日编辑

    不要将部分视图作为剃须刀页面,您只需提交到一个剃须刀页面后面的帖子处理程序即可。

    另外,asp-page 应该使用正确的路径,如果你把你的部分视图放在同一个文章文件夹中,那么它会变成asp-page="Delete"

    演示:

    1.创建局部视图为Pages/Articles/MyDeletePartilaView.cshtml:

    @model Models.Article
    
    <div class="modal" tabindex="-1" role="dialog" id="deletionModal">
        <form id="deletionModalForm" asp-page="Delete" method="post">
            <div class="modal-dialog modal-dialog-centered" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title">Delete Article</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <p>Are you sure you want to delete the article "@Model.Title"?</p>
    
                        <input type="hidden" asp-for="@Model.Id" />
                    </div>
                    <div class="modal-footer">
                        <button type="submit" class="btn btn-danger">Delete</button>
                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
                    </div>
                </div>
            </div>
        </form>
    </div>
    

    2.Pages/Articles/View.cshtml

     <partial name="MyDeletePartilaView.cshtml" model="Model.Article" />
    

    3.Pages/Articles/Delete.cshtml

    @page
    @model RazorpagesCore.Pages.Movies.DeleteModel
    

    4.Pages/Articles/Delete.cshtml.cs

    public class DeleteModel : PageModel
    {
       public async Task<IActionResult> OnPostAsync(int? id)
        {
           //your delete logic         
    
        }
    }
    

    【讨论】:

    • 嘿,我试过了。似乎Delete.cshtml.cs 中的OnPostAsync 实际上并没有被调用。我做了一些调试,表格最终发布到Index.cshtml.cs。有什么想法可以解决这个问题吗?
    • @Matthew Miller 在您的情况下,asp-page 可能设置不正确,您可以随时按 F12 检查按钮的formaction 属性。在我的示例中,_Delete.cshtmlPages/Shared/_Delete.cshtmlPages/Articles/Delete.cshtml 下的 Post 处理程序。
    • 我已验证我有相同的设置,但Index.cshtml.cs 中的后处理程序仍在被调用,而不是Delete.cshtml.cs 中的那个。我检查了应用程序生成的 HTML,按钮没有表单操作:&lt;button type="submit" class="btn btn-danger" formaction=""&gt;Delete&lt;/button&gt;.
    • 另外,如果这有助于提供上下文,我会在应用程序的不同部分使用另一个部分视图遇到同样的问题。在这两种情况下,提交按钮本质上都是发布到错误的处理程序。
    • @Matthew Miller 这很奇怪。你的formaction="" 是我认为的问题,url 没有正确生成......你能展示你的项目结构吗(截图)?
    猜你喜欢
    • 2021-07-27
    • 2013-11-28
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    • 2011-04-15
    • 2021-05-19
    相关资源
    最近更新 更多