Подтвердить что ты не робот

Перенаправление на действие и необходимость передачи данных

У меня есть контроллер, который обрабатывает три действия, характерные для моей проблемы.

Первое - это действие редактирования, которое возвращает представление с формой HTML, которое пользователь может редактировать свойства для данного элемента.

Второе - это действие обновления, которое принимает сообщение назад в браузере и обновляет базу данных. Когда обновление выполнено успешно, мы делаем перенаправление на действие.

Третий - это действие шоу, которое показывает детали данного элемента. Это действие происходит там, где мы перенаправляемся после успешного обновления.

Поток:

Показать → Изменить → Обновить (Sucess: y → перенаправить на Show, n → return Edit)

Я хочу добиться того, чтобы флаг был сработал, когда обновление было успешным, так что на следующем Show view я могу отобразить сообщение для пользователя. Проблема в том, что я не уверен на 100% наилучшим образом переносить эти данные по вызову RedirectToAction(). Я думал, что я использовал строку запроса? Мы уже несем переменные вокруг строки запроса для другой цели, но часть моего скептически относится к злоупотреблениям. Вызов перенаправления ниже.

RouteValueDictionary dict = Foo.GetRouteValues(bar);

RedirectToAction("Show", dict);

Я тоже прочитал этот вопрос, но я не знаю, как использовать свойство TempData, если мне это не нужно.

Question

Спасибо за некоторые предложения!

4b9b3361

Ответ 1

РЕДАКТИРОВАТЬ: Извините, изначально не видел вашей заметки о том, что вы не хотите использовать TempData.

Вкратце - вы хотите, чтобы ваше сообщение снова появилось, если клиент обновляет/перезагружает страницу, на которую они перенаправлены?

Если вы это сделаете, используйте кнопку querystring, например:

return(RedirectToAction("Index", new { message = "hi there!" }));

а затем либо определите

public ActionResult Index(string message) { }

или явно вытащите Request.QueryString [ "message" ] и передайте его в View через ViewData обычным способом. Это также будет работать на браузерах, которые не принимают файлы cookie с вашего сайта.

Если вы НЕ хотите, чтобы сообщение отображалось снова, ASP.NET MVC 1.0 предоставляет коллекцию TempData для этой конкретной цели.

Значения свойств TempData хранятся в состоянии сеанса до следующего запроса от того же браузера, после чего они очищаются - так что если вы поместите что-то в TempData сразу перед возвратом RedirectToAction, он будет доступен на результат перенаправления, но будет немедленно очищен.

Здесь простое изменение в HomeController в стартовом проекте ASP.NET MVC:

public ActionResult Index() {
    ViewData["Message"] = "Welcome to ASP.NET MVC!";
    return View();
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(string submitButton) {
    TempData["message"] = "You clicked " + submitButton;
return(RedirectToAction("Index"));
}

public ActionResult About() {
    return View();
}

и соответствующий вид /Views/Home/Index.aspx должен содержать примерно следующее:

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
  <% if (TempData["message"] != null) { %>
    <p><%= Html.Encode(TempData["message"]) %></p>
  <% } %>
  <% using (Html.BeginForm()) { %>
    <input type="submit" name="submitButton" value="Button One" />
    <input type="submit" name="submitButton" value="Button Two" />
  <% } %>
</asp:Content>

Вы заметите, что сообщение TempData отображается сразу после последовательности POST-REDIRECT-GET, но если вы обновите страницу, она не будет отображаться снова.

Обратите внимание, что это изменение изменилось в ASP.NET MVC 2 - см. "Состояние передачи между методами действий" в в этой статье для получения дополнительной информации.

Ответ 2

Никогда не был поклонником TempData и, кроме того, я не хотел передавать флаг успеха в URL-адрес, поскольку я не хотел видеть

App/Настройки? SaveSuccess = истина

в строке URL браузера.

В моем решении используется временный файл cookie:

[HttpPost]
public ActionResult Settings(SettingsViewModel view)
{
    if (ModelState.IsValid)
    {
        //save
        Response.SetCookie(new HttpCookie("SettingsSaveSuccess", ""));
        return RedirectToAction("Settings");
    }
    else
    {
        return View(view);
    }     
}

и в соответствующей проверке действия Get для присутствия этого Cookie и удалить его:

[HttpGet]
public ActionResult Settings()
{
    var view = new SettingsViewModel();
    //fetch from db and do your mapping
    bool saveSuccess = false;
    if (Request.Cookies["SettingsSaveSuccess"] != null)
    {
        Response.SetCookie(new HttpCookie("SettingsSaveSuccess", "") { Expires = DateTime.Now.AddDays(-1) });
        saveSuccess = true;
    }
    view.SaveSuccess = saveSuccess;
    return View(view);
}

nb это может быть довольно скользкий наклон, если вы начинаете передавать что-либо более сложное, чем логический флаг