ASP.NET MVC Обновить страницу формы Повторная отправка с предупреждением - PullRequest
0 голосов
/ 23 сентября 2019

Внимание, это немного длинная и сложная проблема, поэтому я предлагаю прочитать и помочь мне с этим, только если у вас есть достаточно времени.

Для начала, я работаю в сетипроект, в котором я нахожусь в разделе администрирования, где я могу забанить, удалить или продвинуть пользователя.Итак, это тот же самый вид с тремя различными моделями, включенными, как показано:

Моя модель:

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

Теперь, допустим, я продвигаю пользователя.Я отправляю и получаю это предупреждение «Успех! Пользователь Билли повышен до уровня Модератора».Но теперь, когда я обновляюсь, я снова получаю это предупреждающее сообщение.

Итак, в основном, форма отправляется повторно, и я не могу этого получить.Вот еще мой код:

Контроллер:

[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);
}

В функции promoUser: (Я использовал viewbags просто для проверки перед тем, как поместить реальные функции)

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

В cshtml: (я закрыл первые 2 вкладки и оставил открытыми 3-ю)

enter image description here

В коде 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;
}

В целом, все работает так, как надо, это просто повторная подача формы.Некоторое время я проводил исследования и нашел единственное решение, которое может разрешить более простые случаи, которые не помогают.Только тот, с которым я имею дело, сложен.

Я попробовал 2 вещи.Во-первых, я попытался использовать класс Abstract с виртуальными и добавил дополнительные статические функции.Во-вторых, я попытался использовать другой 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);
        }
    }
}

И как я уже говорил о результате виртуального действия, я упоминал ранее, где вы видите «общедоступный виртуальный ActionResult DevelopmentBoard».И этот абстрактный класс в "NoResubmitAbstract" в dynamicAdminModel.

Код: (абстрактный внутри модели)

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

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

Это работает, когда я использую "this.PreventResubmit (user);"с / без «this.IsResubmit (user)» внутри ActionView.Тем не менее, это работает только в первый раз, не более одного раза, какой тип отстой.Даже если я удаляю PreventResubmit и использую это вместо:

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

К сожалению, не повезло.Но эй!Никакой повторной отправки формы, когда я обновляюсь!


ТАК, в целом, что вы, ребята, думаете?Нужна ли мне помощь с первым подходом или со вторым?Я думаю, что второй имеет больше смысла.Если есть другой подход, пожалуйста, скажите мне.Если у вас есть какие-либо вопросы или если вы хотите, чтобы я добавил больше кода, дайте мне знать, спасибо!Я вернусь через 10 часов.

Ответы [ 2 ]

2 голосов
/ 23 сентября 2019

Поставьте точку останова на вашем контроллере и обновите, она срабатывает?Я не думаю, что это повторная отправка формы.Вам следует сбросить @ViewBag.SuccessCode после показа alert.Потому что, когда вы обновляете ваш скрипт получает то же значение, что и ваш viewbag хранит последний.

Так что после показа оповещения сделайте это

@ViewBag.SuccessCode = ''

Теперь вы не получите никакой избыточности сообщений.

1 голос
/ 23 сентября 2019

Привет ДжейсонДля первого подхода:Я не понимаю, почему вы используете формы дерева для одной модели, но я предлагаю использовать "debbuger;"код на стороне клиента понимает, что не такДля второго подхода:Я предлагаю сначала использовать TempData ["SuccessCode"] для передачи значений между DevelopmentBoard и sbmtPage, а затем использовать viewbag в sbmtPage

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...