【问题标题】:Action method receiving POST request but is never called接收 POST 请求但从未调用的操作方法
【发布时间】:2020-04-11 03:06:24
【问题描述】:

在我的控制器中,我有一个从视图接收响应(200 OK)的操作方法,但它从不运行。该视图有一个 Url.Action,它向 action 方法发送请求,但该方法永远不会被调用。触发操作会导致空白页。

查看:

@model Project.Web.ViewModels.SomeModel

<div class="modal fade" id="@("RemoveThingModal" + Model.Id")" tabindex="-1" role="Dialog" aria-labelledby="@(RemoveThingModal" + Model.Id)">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <form id="@("DeleteForm" + Model.Id)" action="@Url.Action("RemoveThing", "Foo")" method="post">
                @Html.HiddenFor(m => m.Id)
                @Html.HiddenFor(m => m.SomeNameString)

                <div class="modal-header">
                    <button type="button" class="Close" data-dismiss="modal" aria-label="Close"><span aria-hidden="True">&times;</span></button>
                    <h4 class="modal-title" id="@("RemoveThingModal" + Model.Id)">@MainResource.DeleteModalTitle</h4>
                </div>
                <div class="modal-body col-md-12">
                    <div>
                        @MainResource.DeleteModalMessage
                        <h3>@string.Format("{0}: {1}", @MainResource.DataTableColumnThingName, Model.Name)</h3>
                    </div>
                </div>

                <div class="modal-footer col-md-12">
                    <button type="button" class="btn btn-default" data-dismiss="modal">@MainResource.CancelLink</button>
                    <button type="submit" id="#@("deleteSubmitButton" + Model.Id)" class="btn btn-danger">@MainResource.RemoveButton</button>
                </div>
            </form>
        </div>
    </div>
</div>

控制器(FooController):

[HttpPost]
public ActionResult RemoveThing(int barId)
{
    System.Diagnostics.Debug.WriteLine("DEBUG: aaaa");    

    try {
        return RedirectToAction("List");
    }
    catch (Exception e)
    {
        throw new Exception(e.Message);
    }
}

甚至没有调用调试打印语句。在某些时候,它起作用了,但是没有提交更改并且撤消历史记录丢失了。

  • 将视图的 Url.Action 更改为不同控制器中的另一个操作有效。
  • 控制器中的其他操作在从其他视图调用时会起作用。

【问题讨论】:

  • 检查 cshtml 在浏览器上的呈现方式。检查最终的 html 表单标签是否指向正确的操作方法。此外,使用开发工具并在提交页面时查看调用状态。如果您可以检查所有这些并将结果发布回您的帖子将有助于某人指出问题所在。
  • @Thangadurai 表单标签似乎在 DOM 中正确呈现。
  • @Alex 意图是当用户在模式对话框中确认删除/删除时运行操作。我不确定@using (Html.BeginForm() 的优势,但它似乎在系统中的其他地方(尽管少得多)使用。
  • 我将其更改为使用 Html.BeginForm,但问题似乎没有解决。只是@using (Html.BeginForm("RemoveThing", "Foo", FormMethod.Post)),没有其他参数。该方法正在根据VS获取请求(仍然是200 OK),但没有运行。
  • 您的“barId”未绑定。试试这个:@Html.HiddenFor(m =&gt; m.Id, new { id = "barId", Name = "barId" })。请注意,Name 在提交表单时被 MVC 使用。

标签: c# asp.net-mvc razor controller razor-pages


【解决方案1】:

您的操作需要一个名称为barId 的整数;您将其发送到Id,因此找不到该操作。这是您需要的:

@model Project.Web.ViewModels.SomeModel

<div class="modal fade" id="@("RemoveThingModal" + Model.Id")" tabindex="-1" role="Dialog" aria-labelledby="@(RemoveThingModal" + Model.Id)">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            @using (Html.BeginForm("RemoveThing","Foo", FormMethod.Post)
            {
                @Html.AntiForgeryToken()
                @Html.HiddenFor(m => m.Id, new { id = "barId", Name = "barId" })
                @Html.HiddenFor(m => m.SomeNameString)

                <div class="modal-header">
                    <button type="button" class="Close" data-dismiss="modal" aria-label="Close"><span aria-hidden="True">&times;</span></button>
                    <h4 class="modal-title" id="@("RemoveThingModal" + Model.Id)">@MainResource.DeleteModalTitle</h4>
                </div>
                <div class="modal-body col-md-12">
                    <div>
                        @MainResource.DeleteModalMessage
                        <h3>@string.Format("{0}: {1}", @MainResource.DataTableColumnThingName, Model.Name)</h3>
                    </div>
                </div>

                <div class="modal-footer col-md-12">
                    <button type="button" class="btn btn-default" data-dismiss="modal">@MainResource.CancelLink</button>
                    <button type="submit" id="#@("deleteSubmitButton" + Model.Id)" class="btn btn-danger">@MainResource.RemoveButton</button>
                </div>
            }
        </div>
    </div>
</div>

关于行动:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RemoveThing(int barId)
{
    System.Diagnostics.Debug.WriteLine("DEBUG: aaaa");    

    try {
        return RedirectToAction("List");
    }
    catch (Exception e)
    {
        throw new Exception(e.Message);
    }
}

添加防伪验证与您的问题无关,但它是防止跨站点脚本攻击的好习惯。

【讨论】:

  • Url.Action(string, string) 只返回一个字符串,它是指定控制器和操作的 URL。它与方法无关,因为该方法由 form 元素中的 method= 属性定义。见this SO question
  • 谢谢,@NathanMiller。将其与@Html.ActionLink 混合在一起,这始终是 GET!当实际上它是 MVC 自动绑定时,专注于这个问题。请参阅上面的更新。
  • 是的,我认为这可能是问题所在,但空白页结果和状态代码 200 似乎很奇怪,就像某处有过载做不同的事情一样。如果绑定不正确,我会期待不同的结果。嗯,有时是 MVC 的奥秘。
  • @NathanMiller,你是对的;为什么它会做 200 状态和空白?但是我已经看到了 MVC 的怪异之处,以至于这可以进入百科全书 :)
猜你喜欢
  • 2022-06-25
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 2018-04-02
  • 2016-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多