В моем приложении я сохраняю объект в сеансе, который передается веб-службе для возврата данных для отображения в таблице. Если сеанс существует, он не будет просить пользователя ввести свежие данные. Однако если пользователь выбирает ссылку под названием «Новый список», данные сеанса будут очищены, и пользователю будет предложено ввести новые данные.

В моем коде у меня есть привязка, определенная так:

<a href="@Url.Action("NewList", "Alert")"> New List</a>

Который вызовет это действие контроллера:

public ActionResult NewList()
{
     Session["new_list"] = "y";
     return RedirectToAction("List");
}

И затем продолжите выполнять это действие:

 public ActionResult List()
    {
         if ((string)Session["new_list"] == "y")
         {
             //clear session variables, load fresh data from API
         }else{
             //display blank table. Ask user to input data to retrieve a list
         }
      ....
     }

Теперь у меня возникает проблема, когда пользователь уходит со страницы списка, а затем возвращается назад с помощью кнопки «Назад» в браузере, он все еще вызывает newlist. В истории браузера вместо хранения List он хранит newlist, что приводит к очистке переменной сеанса. Что я могу сделать, чтобы не допустить этого или есть другой механизм для использования в C # MVC, который может помочь мне достичь желаемого эффекта.

1
Notaras 24 Апр 2017 в 08:28

2 ответа

Лучший ответ

Ваша главная проблема в том, что действие NewList использует GET , когда оно действительно должно быть POST .

Запрос GET никогда не должен изменять состояние ресурса, а просто возвращает текущее состояние ресурса; в то время как запрос POST позволяет изменить ресурс.

Поскольку вы разрешаете вызывать действие NewList с помощью запроса GET, браузер пользователя предполагает (вполне справедливо со своей стороны), что ничего плохого / нежелательного не произойдет, если он просто повторяет запрос в будущем, например, когда пользователь использует кнопку назад.

Если вместо этого выдается запрос POST, пользовательский браузер никогда не будет повторно выдавать запрос, пока пользователь не подтвердит, что он на самом деле намеревался повторно его выполнить.

Тогда решение вашей проблемы - это изменить стандартный шаблон PRG : POST / Redirect / GET ; отправьте запрос POST для изменения состояния, перенаправьте браузер пользователя на другую страницу и получите страницу результатов. В этой схеме нажатие кнопки «назад» фактически пропустит действие изменения состояния и перейдет на предыдущую страницу, на которой был пользователь.

Для этого в MVC:

[HttpPost]
public ActionResult NewList()
{
    //clear session variables, load fresh data from API
    return RedirectToAction("List");
}

public ActionResult List()
{
    // whatever needs to happen to display the state
}

Это означает, что вы не можете предоставить действие «Новый список» непосредственно в виде гиперссылки на странице, поскольку они всегда будут выдавать запросы GET. Вам нужно будет использовать минимальную форму, например, так: <form method="post" action="@Url.Action("NewList", "Alert")"><button type="submit">New List</button></form>. Вы можете настроить кнопку так, чтобы она выглядела как обычная гиперссылка по желанию.

1
Matt Wilkinson 24 Апр 2017 в 06:25

Причина, по которой он хранит NewList, заключается в том, что вы перенаправляете на «Alert / NewList», и это строка в вашем URL для выполнения действия «NewList», поэтому всякий раз, когда вы нажимаете кнопку «Назад», браузер получает этот «Alert / NewList» URL Отсюда и его удар по действию "NewList". Но сейчас я не понимаю, почему сессия становится понятной. потому что вы инициализируете сеанс в самом «NewList». Тем не менее я предлагаю вам использовать локальное хранилище для назначения значений сессией.

0
Pooja K. 24 Апр 2017 в 05:50
43580390