RedirectToAction (..) со сложным глубоким объектом не работает - PullRequest
9 голосов
/ 29 августа 2009

Я пытаюсь передать объект от одного действия контроллера другому. Объект, который я передаю, выглядит примерно так:

public class Person
{
   public string Name { get; set; }
   public List<PhoneNumber> PhoneNumbers {get; set; }
   public List<Address> Addresses { get; set; }
}

Мой контроллер выглядит так:

public class DialogController : Controller
{
    public ActionResult Index()
    {
        // Complex object structure created
        Person person = new Person();
        person.PhoneNumbers = new List();
        person.PhoneNumbers.Add("12341324");

        return RedirectToAction("Result", "Dialog", person);

    }

    public ActionResult Result(Person person)
    {
        string number = person.PhoneNumbers[0].ToString();
        return View();
    }
}

Сбой метода result с исключением нулевого указателя, поскольку список PhoneNumbers внезапно становится пустым после вызова действия Result с помощью метода RedirectToAction ().

Кто-нибудь видел этот тип поведения раньше?

Приветствия

Peter

Ответы [ 4 ]

7 голосов
/ 29 августа 2009

Вам действительно нужно перенаправить на другое действие? RedirectToAction вызывает новый http-запрос, поэтому TempData работает. Не могли бы вы просто вызвать действие Result напрямую, как это?

public ActionResult Index()
{
    // Complex object structure created
    Person person = new Person();
    person.PhoneNumbers = new List();
    person.PhoneNumbers.Add("12341324");

    return Result(person);

}

Редактировать Если ваше приложение не выполняет больше, чем вы показали в вопросе, это не похоже на то, что вам действительно нужно действие Index. Вы можете переместить код, который создает нового человека, в приватный CreatePerson метод. В вашем действии Result, если person равно нулю, вызовите метод CreatePerson. Действие Index можно полностью исключить, но для этого потребуется изменить маршруты. Или просто позвольте return RedirectToAction("Result", "Dialog"); быть единственной строкой кода в вашем Index действии.

На самом деле, после разделения проблем MVC, этот CreatePerson метод, вероятно, должен быть методом внутри кода вашей модели. Контроллер не должен содержать логику создания нового Person. Это действительно принадлежит модели.

5 голосов
/ 29 августа 2009

Я согласен с @Dennis - если вы не хотите, чтобы URL изменился, вам придется подумать о чем-то другом. Причина в том, что RedirectToAction не сериализует данные, а просто перебирает свойства объекта значений маршрута, создавая строку запроса, ключами которой являются имена свойств, а значениями - строковое представление значений свойств. Если вы хотите изменить URL-адрес, тогда, вероятно, самый простой способ сделать это - использовать TempData, хотя вы также можете сохранить элемент в базе данных, передать идентификатор методу Result и восстановить его оттуда.

2 голосов
/ 05 марта 2014

Хотя это старый вопрос, я нашел отличный ответ на него в том, что я считаю дублирующим вопросом. Ключом является конструктор RouteValueDictionary .

return RedirectToAction("Result", "Dialog", new RouteValueDictionary(person))

Поскольку у вас есть коллекции, это делает его немного сложным, , но этот другой ответ очень хорошо описывает этот вопрос .

0 голосов
/ 17 марта 2015

Для всех, кому действительно нужно вызвать какое-то действие и вернуть представление из другого контроллера со сложным объектом, и не хотят (или не могут) передавать объект в TempData. Я использую в своем приложении очень некрасивое, но рабочее решение:

protected ActionResult InternalRedirectToAction(string action, string controller, object model)
{
    var htmlHelper = new HtmlHelper(new ViewContext(
                              ControllerContext,
                              new WebFormView(ControllerContext, "HACK"),
                              new ViewDataDictionary(),
                              TempData, //for sharing TempData between Actions
                              new StringWriter()),
                        new ViewPage());

    var otherViewHtml = htmlHelper.Action(action, controller, model);
    return Content(otherViewHtml.ToString());
}

Вдохновленный ответом, найденным здесь: https://stackoverflow.com/a/4360019/1341409

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