我正在创建一个小型MVC应用程序,并将User对象从控制器传递到另一个控制器中的ActionResult方法。 User对象的一个属性是名为Properties的Property对象列表。
这是一个问题:当User对象最终传递给相关的View时,它的列表不包含任何属性。
以下是设置:
用户类:
public class User
{
public int Id {get;set;}
public List<Property> Properties {get;set;}
}
的AccountController
public ActionResult LogOn(int userId, string cryptedHash)
{
//code to logOn (this works, promise)
User user = dbContext.getUser(userId);
//debugging shows the user contains the list of properties at this point
return RedirectToAction("UserHome", "Home", user);
}
的HomeController
public ActionResult UserHome(User user)
{
ViewBag.Messaage = "Hello, " + user.Forename + "!";
return View(user); //debugging shows that user.Properties is now empty(!)
}
UserHome.cshtml查看
@model emAPI.Model_Objects.User
@{
ViewBag.Title = "UserHome";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>UserHome</h2>
<div>
@Model.Forename, these are your properties:
<ul>
@foreach (var property in @Model.Properties)
{
<li>property.Name</li>
}
</ul>
</div>
视图加载没有任何问题 - @Model.Forename
很好,但就HomeController
而言user.Properties
收到它时是空的,虽然我知道它不是{ {1}}发送了它。
感谢任何人提供的任何帮助或建议。
答案 0 :(得分:1)
重定向时无法传递整个复杂对象。只有简单的标量参数。
实现这一目标的标准方法是通过发出表单身份验证cookie来验证用户,该cookie允许您在所有后续操作中存储用户ID。然后,如果在控制器操作中,您需要用户详细信息,例如forename或您只是查询数据存储的任何内容,以使用id从任何位置检索用户。在创建新的ASP.NET MVC 3应用程序时,只需看看Account控制器的实现方式。
所以:
public ActionResult LogOn(int userId, string cryptedHash)
{
//code to logOn (this works, promise)
User user = dbContext.getUser(userId);
//debugging shows the user contains the list of properties at this point
// if you have verified the credentials simply emit the forms
// authentication cookie and redirect:
FormsAuthentication.SetAuthCookie(userId.ToString(), false);
return RedirectToAction("UserHome", "Home");
}
并且在目标操作中只需从User.Identity.Name
属性中获取用户ID:
[Authorize]
public ActionResult UserHome(User user)
{
string userId = User.Identity.Name;
User user = dbContext.getUser(int.Parse(userId));
ViewBag.Messaage = "Hello, " + user.Forename + "!";
return View(user);
}
啊,请,请不要使用ViewBag。请改用视图模型。如果您的视图所关心的只是通过显示他的forename来欢迎用户,只需构建一个包含forename属性的视图模型,然后将此视图模型传递给视图。视图不关心您的用户域模型,也不应该关注。
答案 1 :(得分:0)
RedirectToAction
方法向浏览器返回HTTP 302
响应,这会导致浏览器对指定的操作发出GET
请求。您不应该考虑将复杂对象传递给下一个操作方法。
在这种情况下,您可以将用户对象保留在Session
变量中,并在其余位置访问它。
public ActionResult LogOn(int userId, string cryptedHash)
{
User user = dbContext.getUser(userId);
if(user!=null)
{
Session["LoggedInUser"]=user;
return RedirectToAction("UserHome", "Home");
}
}
public ActionResult UserHome()
{
var loggedInUser= Session["LoggedInUser"] as User;
if(loggedInUser!=null)
{
ViewBag.Messaage = "Hello, " + user.Forename + "!";
return View(user);
}
return("NotLoggedIn");
}