我正在尝试将一个对象从一个控制器动作传递给另一个.我传递的对象或多或少看起来像这样:
public class Person
{
public string Name { get; set; }
public List<PhoneNumber> PhoneNumbers {get; set; }
public List<Address> Addresses { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的控制器看起来像这样:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
结果方法因空指针异常而失败,因为在使用RedirectToAction()方法调用Result操作后,PhoneNumbers列表突然为null.
以前有没有人见过这种行为?
干杯,
彼得
你真的需要重定向到其他动作吗?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);
}
Run Code Online (Sandbox Code Playgroud)
编辑除非你的应用程序比你在问题中显示的内容做得更多,否则看起来你真的不需要索引操作.您可以将创建新人的代码移动到私有CreatePerson方法中.在您的Result操作中,如果person为null,则调用该CreatePerson方法.Index可以完全取消该操作,但这需要修改您的路线.或者只是让return RedirectToAction("Result", "Dialog");你成为Index行动中唯一的代码.
实际上,在关注MVC后,该CreatePerson方法可能应该是模型代码中的一种方法.控制器不需要包含创建新的逻辑Person.这真的属于模型.
我同意@Dennis - 除非你想让Url改变,否则你将不得不考虑别的东西.原因是RedirectToAction不会序列化数据,它只是遍历路由值对象中的属性,构造一个查询字符串,其中键是属性名称,值是属性值的字符串表示形式.如果您想要更改Url,那么使用TempData可能是最简单的方法,尽管您也可以将项目存储在数据库中,将id传递给Result方法,然后从那里重新构建它.