MVC - Передача данных с помощью RedirectToAction () - PullRequest
59 голосов
/ 23 марта 2009

Я хотел бы взять данные, введенные в пользовательскую форму MVC, и отобразить их в другом виде.

Класс имеет следующую приватную переменную:

IList<string> _pagecontent = new List<string>();

Следующее действие принимает объект FormCollection, проверяет его и передает его в представление «Предварительный просмотр» в виде списка:

[Authorize(Roles = "Admins")]
[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateContent(FormCollection collection)
{
    if (ModelState.IsValid)
    {
        string PageToInsert = collection["PageToInsert"];
        string PageHeader = collection["PageHeader"];
        string PageBody = collection["PageBody"];

        //validate, excluded...

        _pagecontent.Add(PageToInsert);
        _pagecontent.Add(PageHeader);
        _pagecontent.Add(PageBody);

    }
    return RedirectToAction("Preview", _pagecontent);
}

В окне предварительного просмотра имеется следующая директива страницы для передачи строго типизированного списка объектов:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Template.Master" Inherits="System.Web.Mvc.ViewPage<List<string>>" %>

Я ожидал бы, что смогу использовать объект Model для получения моих данных, но, увы, не могу. В следующей строке я получаю исключение error index out of bounds, в котором указывается, что индекс должен быть неотрицательным и меньше размера коллекции:

<% if (Model[0].ToString() == "0") { %>

И некоторые странные параметры были добавлены в URL, поскольку он разрешает http://localhost:1894/Admin/Preview?Capacity=4&Count=3

Итак, у меня два вопроса:

  1. Когда я вызываю RedirectToAction и передаю его моему списку, почему он недоступен в объекте модели представления?
  2. Как правильно выполнить то, что я пытаюсь сделать, а именно передать коллекцию строк в представление для отображения там?

Ответы [ 8 ]

55 голосов
/ 23 марта 2009

Попробуйте использовать TempData. Это как единичный объект сеанса. Вы помещаете нужные значения в TempData, немедленно перенаправляете и выводите их. Здесь есть хорошая рецензия: http://blogs.teamb.com/craigstuntz/2009/01/23/37947/

11 голосов
/ 25 апреля 2012

Будьте осторожны при использовании TempData. Он отлично работает в среде с одним сервером, но в облачной среде он может работать не так, как ожидалось, поскольку вы не можете гарантировать, что запрос попадет на ту же машину. Это происходит потому, что TempData полагаются на сеанс asp.net. Но если вы используете другой менеджер сессий, такой как SQL или AppFabric Cache, он будет работать нормально.

7 голосов
/ 24 марта 2009

Второй параметр RedirectAction - это routeValues, а не модель.

protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues);

Попробуйте использовать TempData для модели. Это для сохранения данных между перенаправлениями.

4 голосов
/ 23 марта 2009

Проблема с RedirectToAction заключается в том, что он возвращает HTTP 302, и браузер сам по себе выполняет новый HTTP-запрос. Вы можете рассмотреть возможность использования файла cookie и / или объекта сеанса для сохранения данных между запросами.

3 голосов
/ 24 июля 2009

Это не работает, потому что RedirectToAction фактически отправляет обратно Http 302 в браузер. Когда браузер получает эти 302, он делает новый запрос к серверу, запрашивая новую страницу. Новый запрос, новые временные переменные.

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

Итак, вместо:

return RedirectToAction("Preview", _pagecontent);

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

return PreviewLogic(_pagecontent);

Вы также можете использовать dicData TempData [] для сохранения данных для следующего запроса, как сказали другие, но тогда вы не избежите дополнительных 302 обращений к серверу.

2 голосов
/ 23 марта 2009

Похоже, вы пытаетесь сделать:

public ActionResult UpdateContent(FormCollection form) {
    ...
    return View("Preview", _pagecontent);
}

Обратите внимание, что перенаправление считается «чистым списком» для браузера (за исключением таких вещей, как файл cookie для аутентификации). Вы не можете сказать браузеру передавать информацию следующему запросу, так как следующий запрос должен быть в состоянии стоять самостоятельно. Все, что вам нужно сделать, это сказать браузеру, какой URL запрашивать дальше. В ASP.NET MVC, когда вы передаете объект arguments в RedirectToAction, публичные свойства этого объекта добавляются в качестве параметров строки запроса к сгенерированному URL.

0 голосов
/ 05 мая 2014

Разве вы не можете просто сделать 2 результата действия с одинаковым именем и пометить 1 из них HttpPost?

    public ActionResult UpdateContent(FormCollection preview = null)
    {
        return View(preview);
    }
    [HttpPost]
    public ActionResult UpdateContent(FormCollection collection = null, bool preview = false)
    {
        if (preview)
            return UpdateContent(collection);
        else
            return UpdateContent(null);
    }
0 голосов
/ 23 марта 2009

Похоже, вы ищете команду UpdateModel:

Ознакомьтесь с постом ScottGu в блоге на тему:

Улучшены методы UpdateModel и TryUpdateModel

...