【问题标题】:ASP.NET MVC Reload page form Re-submission with alertASP.NET MVC 重新加载页面表单重新提交并发出警报
【发布时间】:2020-01-23 02:40:28
【问题描述】:

注意,这是一个有点长和复杂的问题,所以我建议只有在你有足够的时间的情况下阅读并帮助我解决这个问题。

首先,我正在做一个网络项目,我在管理部分可以禁止、取消禁止或提升用户。因此,这是一个包含 3 个不同模型的相同视图,如下所示:

我的模特:

public class dynamicAdminModel : NoResubmitAbstract
{
    public UserSuspension userSus { get; set; }
    public UserUnban userUnban { get; set; }
    public PromoteUser promoteUser { get; set; }
}

现在,假设我正在提升一个用户。我提交并收到警告消息“成功!用户 Billy 已被提升为版主。”。但是现在当我刷新时,我再次收到该警报消息。

所以,基本上,表单正在重新提交,但我无法提交。这是我的更多代码:

控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult DevelopmentBoard(dynamicAdminModel user)
{
    if (ModelState.IsValid)
    {
        string str = getDevString(user);
        switch (str)
        {
            case "Banning":
                userBanning(user.userSus);
                break;
            case "Unbanning":
                unbanUser(user.userUnban.UserName);
                break;
            case "PromoteUser":
                promoteUser(user.promoteUser.UserName, user.promoteUser.Hierarchy);
                break;
        }
    }
    return View(user);
}

在promoteUser函数中:(我使用viewbags只是为了测试,然后再放入实际函数)

private void promoteUser(string userName, string Hierarchy)
{
    ViewBag.SuccessCode = "UserPromoted";
    ViewBag.User = userName;
    ViewBag.Hierarchy = Hierarchy;
}

在 cshtml 中:(我关闭了前 2 个选项卡并打开了第 3 个选项卡)

在 Javascript 代码中:

switch ("@ViewBag.SuccessCode") {
    case "UserBanned":
        alert("User has been banned successfully!");
        break;
    case "UserUnbanned":
        alert("User has been successfully unbanned!");
        break;
    case "UserPromoted":
        alert("Success!\nUser @ViewBag.User has been promoted to @ViewBag.Hierarchy.");
        break;
}

总的来说,一切正常,只是重新提交表单。我已经研究了一段时间,发现唯一可以解决更简单但无济于事的解决方案。只是我正在处理的这个很复杂。

我尝试了两件事。一,我尝试使用带有虚拟的抽象类并添加了额外的静态函数。二、我尝试使用其他的ActionResult。


让我详细说明第二种方法。基本上,在我提交之后,我会转到其他操作结果,而其他操作结果会自动将我带回。但是,问题是,如果我按提交,则不会弹出警报。谢天谢地,表单没有重新提交。

基本上是Controller中的这段代码:

public ActionResult sbmtPage()
{
    return RedirectToAction("DevelopmentBoard", "Administrator");
}

我在 ActionResult DevelopmentBoard 中使用“return RedirectToAction("sbmtPage", "Administrator")"。


第一种方法稍微复杂一些。我在控制器内部创建了一个额外的静态类,其中包含 2 个函数; IsResubmit 和 PreventResubmit。

代码:

public static class ControllerExtensions
{
    [NonAction]
    public static bool IsResubmit(this System.Web.Mvc.ControllerBase controller, NoResubmitAbstract vModel)
    {
        try
        {
            return (Guid)controller.TempData["PreventResubmit"] != vModel.PreventResubmit;
        }
        catch (Exception)
        {
            return false;
        }
    }

    [NonAction]
    public static void PreventResubmit(this System.Web.Mvc.ControllerBase controller, params NoResubmitAbstract[] vModels)
    {
        var preventResubmitGuid = Guid.NewGuid();
        controller.TempData["PreventResubmit"] = preventResubmitGuid;
        foreach (var vm in vModels)
        {
            vm.SetPreventResubmit(preventResubmitGuid);
        }
    }
}

正如我之前提到的虚拟操作结果,您可以看到“公共虚拟操作结果开发板”。以及 dynamicAdminModel 中“NoResubmitAbstract”中的抽象类。

代码:(模型内部的抽象)

public abstract class NoResubmitAbstract
{
    public Guid PreventResubmit { get; set; }

    public void SetPreventResubmit(Guid prs)
    {
        PreventResubmit = prs;
    }
}

这在我使用“this.PreventResubmit(user);”时有效在 ActionView 中有/没有“this.IsResubmit(user)”。但是,它只在第一次起作用,不超过一次,这很糟糕。即使我删除了 PreventResubmit 并改用它:

if(this.IsResubmit(user)){
    if(ModelState.IsValid){
        Code....
    }
}

不幸的是,没有运气。但是,嘿!每次刷新都不会重新提交表单!


所以,总的来说,你们怎么看?我需要第一种方法或第二种方法的帮助吗?我觉得第二个更有意义。如果有其他方法,请告诉我。如果您有任何问题或需要我提供更多代码,请告诉我,谢谢!我会在 10 小时后回来。

【问题讨论】:

  • 表单重新提交弹出窗口是一个浏览器警告,这是一件好事,我希望浏览器告诉我刷新页面时我可能会购买另一张机票,不应该解决它.您可以做的是在单击按钮时使用 ajax 发布到您的服务器,这样当您刷新时,它不是重新提交,因此不会发出警告。
  • AJAX 对我来说是一件非常有趣的事情。我会知道的,只是我只希望该表单不重新提交,也不让重新提交的警告消息弹出。我使用下面答案中的另一个 ActionResult 和 TempData 解决了它。

标签: javascript c# asp.net-mvc razor model-view-controller


【解决方案1】:

嗨,杰森
对于第一种方法:
我不明白你为什么对一个模型使用树形,但我建议使用“debbuger;”客户端中的代码了解问题所在
对于第二种方法:
我建议首先使用 TempData["SuccessCode"] 在 DevelopmentBoard 和 sbmtPage 之间传递值,然后在 sbmtPage 中使用 viewbag

【讨论】:

  • 成功了,你是英雄。 TempData 是我刚学到的新东西。我所做的是在PromoteUser 函数中添加TempData,然后如果其中一个TempData 不为空,则将其传递回DevelopmentBoard ActionResult。总的来说,它有效,并且表格没有重新提交!非常感谢!
【解决方案2】:

在你的控制器上放一个断点并刷新,它成功了吗?我不认为它重新提交表格。您应该在显示alert 后重置您的@ViewBag.SuccessCode。 因为当你刷新你的脚本时,你的 viewbag 正在存储最后一个。

所以在显示警报后,执行此操作

@ViewBag.SuccessCode = ''

现在您不会得到任何消息冗余。

【讨论】:

  • 我想试试。我只是不太确定该表格是否可能会重新提交,即使该消息没有出现。我只是不想看到重新提交表单的警告。
猜你喜欢
  • 2014-01-11
  • 1970-01-01
  • 2013-11-19
  • 2013-10-07
  • 2017-02-03
  • 1970-01-01
  • 2019-11-26
  • 2015-11-16
  • 2021-11-12
相关资源
最近更新 更多