Перенаправить к действию и необходимо передать данные - PullRequest
28 голосов
/ 29 июля 2010

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

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

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

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

Поток:

Показать -> Изменить -> Обновить (Sucess: y -> перенаправить на Показать, n -> вернутьИзменить)

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

RouteValueDictionary dict = Foo.GetRouteValues(bar);

RedirectToAction("Show", dict);

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

Вопрос

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

Ответы [ 2 ]

41 голосов
/ 29 июля 2010

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

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

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

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 - см. «Passin».g Состояние между методами действий »в этой статье для получения дополнительной информации.

4 голосов
/ 08 февраля 2015

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

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

в адресной строке браузера.

Мое решение использует временный файл 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 это может быть довольно скользкий уклон, если вы начнете проходить что-то более сложное, чем логический флаг

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