2010-07-29 2 views
26

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

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

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

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

Течение:

Show -> Edit -> Update (Sucess: у -> перенаправлять Показать, п ​​-> вернуться Edit)

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

RouteValueDictionary dict = Foo.GetRouteValues(bar); 

RedirectToAction("Show", dict); 

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

Question

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

ответ

39

EDIT: Извините, изначально не было видно вашей заметки о том, что вы не хотите использовать TempData.

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

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

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

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

public ActionResult Index(string message) { } 

или явно вытаскивать Request.QueryString [ "сообщение"] и передать его Просмотр через 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 - см. «Состояние передачи между методами действий» в this article для получения дополнительной информации.

+0

Спасибо за приятное объяснение. Я собираюсь взглянуть на статью, так как мы на 2.0. Я упомянул в своем посте, что я хотел держаться подальше от свойства TempData, но если это дефакто-способ, возможно, это будет не так уж плохо. Еще раз спасибо. –

+4

Это старый вопрос, но ссылка сейчас не работает :( –

+3

Современная (ish) рабочая ссылка для этой статьи (прокрутка примерно на полпути вниз): http://msdn.microsoft.com/en-us/library/dd394711 (v = vs.100) .aspx – Jaxidian

4

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

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

в URL-адрес браузера.

Мое решение использует временную печенье:

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

и в соответствующем Получить действия проверки на наличие этого 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); 
} 

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

+0

Привет - в чем опасность, если вы передадите строку, которая будет сообщением о подтверждении значения cookie (например, ваши настройки сохранены в порядке или не сохранены настройки)? – Bartosz

+0

@ Bartosz вы можете просто используйте логическое значение и затем настройте ответное сообщение на основе этого? Если ответное сообщение может быть более двух вещей, тогда вам нужно будет прагматично об этом - он чувствует себя немного неправильно - то есть, если у вас несколько сообщений об ошибках, то это должно перед перенаправлением - если ваши настройки не сохранялись, то это должно обрабатываться инструкцией else в первом фрагменте кода и не должно быть перенаправлено – wal

Смежные вопросы