好吧,所以我花了五六个小时来完成这项工作无济于事。我相信,我正在使用ASP.NET MVC 4和EF 5.0进行C#。这是我的问题:我的控制器中有一个方法将一个自定义类作为参数(这些名称以糖果为主题的混淆:P)。 ViewError类如下所示:
public class ViewError<T> where T : class
{
public T ModelObject { get; set; }
public string Message { get; set; }
public ViewError(string message, T modelObject)
{
Message = message;
ModelObject = modelObject;
}
public ViewError()
{
Message = null;
ModelObject = default(T);
}
}
(这是一个通用的,所以我可以在代码中找出ModelObject的类型。但是它无关紧要;我已经测试了它采用通用的'对象'并且发生同样的问题。)
控制器方法如下所示。它只是询问谁在吃糖果,如果有ViewError,它会显示消息。 (该视图有一个显示ViewBag.Message的段落。)
public ActionResult EatCandy(ViewError<EatCandyViewModel> error)
{
ViewBag.BrandList = new SelectList(db.Brands, "ID", "Name");
// If there's a notification, pass it to the view, along with the model
if(error.Message != null)
{
ViewBag.Message = error.Message;
return View(error.ModelObject);
}
return View();
}
在帖子上:
[HttpPost]
public ActionResult EatCandy(EatCandyViewModel viewModel)
{
if(ModelState.IsValid)
{
CandyEater eater = (CandyEater)viewModel;
db.CandyEaters.Add(eater);
db.SaveDatabase(); // Custom convenience wrapper for SaveChanges()
return RedirectToAction("ChooseCandyToEat", eater);
}
return View(viewModel);
}
非常标准的东西。现在,在ChooseCandyToEat方法中,它会显示一个可供特定品牌吃的糖果列表。如果该品牌没有任何可用的糖果,我希望它将错误发送回EatCandy方法(通过ViewError对象),告诉他们他们没有糖果可以吃,并将模型送回去,以便食者不会我必须再次输入他们的信息,只需选择不同品牌的糖果。
public ActionResult ChooseCandyToEat(CandyEater eater)
{
// Get the list of candy associated with the brand.
IEnumerable<Candy> candyList = db.Candies.Where(b => b.Brand == eater.DesiredBrand)
.Where(e => !e.Eaten);
// If the brand has no candy, return an error message to the view
if(candyList.Count() == 0)
{
EatCandyViewModel viewModel = (EatCandyViewModel)eater;
ViewError<EatCandyViewModel> viewError = new ViewError<EatCandyViewModel>("Oh noes! That brand has no candy to eat!", viewModel.Clone()); // This is a deep clone, but even if it wasn't, it would still be weird. Keep reading.
return RedirectToAction("EatCandy", viewError);
}
return View(candyList);
}
根据我的理解,这应该都有效。现在这里是奇怪的部分 - 我可以通过调试消息和Watch窗口(使用Visual Studio)确认ViewError是否正确创建并在其ModelObject中保存viewModel的深层克隆(我必须将其转换回来,因为EatCandy方法期望EatCandyViewModel作为参数)。但是,当我向前迈进并将ViewError传递给EatCandy时,其中的ModelObject为null!我原本以为这是因为它只将viewModel的引用传递给了对象并且它被垃圾收集了,这就是我添加Clone()方法的原因。但是,字符串也是一种引用类型,但它正好运行。为什么不是对象?有谁知道吗?
如果您需要更多信息,请询问。并且无视这个数据库的荒谬 - 我故意混淆了它,而不仅仅是愚蠢。
答案 0 :(得分:0)
这不起作用。 RedirectToAction导致302到浏览器,它无法携带复杂的模型。
有一些替代方案,您可以使用TempData存储模型,执行重定向并检索数据。你甚至可以直接调用EatCandy动作而不是重定向,但是自动匹配视图将不起作用,你必须在EatCandy动作结束时强制使用“EatCandy”视图名称。