MVC-передача данных с RedirectToAction()



Я хотел бы взять данные, введенные в пользовательской форме 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>>" %>


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



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


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



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




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

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

542   8  

8 ответов:

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

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

второй параметр RedirectAction-это routeValues, а не model.

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

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

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

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

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

, вместо:

return RedirectToAction("Preview", _pagecontent);

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

return PreviewLogic(_pagecontent);

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

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

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

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

не можете ли вы просто сделать 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);
    }

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

Проверьте сообщение в блоге ScottGu по теме:

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

Comments

    Ничего не найдено.