MVC控制器/视图删除模型属性

时间:2012-07-25 12:34:55

标签: asp.net-mvc-3

我正在创建一个小型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}}发送了它。

感谢任何人提供的任何帮助或建议。

2 个答案:

答案 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");
}