0

我正在创建一个小型 MVC 应用程序,并将一个用户对象从一个控制器传递到另一个控制器中的 ActionResult 方法。User 对象的属性之一是称为Properties 的Property 对象列表。

问题是:当用户对象最终传递给相关视图时,它的列表不包含任何属性。

这是设置:

用户等级:

public class User
{
   public int Id {get;set;}
   public List<Property> Properties {get;set;}
}

帐户控制器

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);
}

家庭控制器

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.PropertiesAccountController

任何人必须提供的任何帮助或建议都将被感激地接受。

4

2 回答 2

1

重定向时不能传递整个复杂对象。只有简单的标量参数。

实现这一点的标准方法是通过发出表单身份验证 cookie 来对用户进行身份验证,这将允许您在所有后续操作中存储用户 ID。然后,如果在控制器操作中您需要用户详细信息,例如名字或任何您只需查询数据存储以使用 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。改用视图模型。如果您的视图所关心的只是通过显示他的名字来欢迎用户,只需构建一个包含名字属性的视图模型,然后将此视图模型传递给视图。该视图不关心您的用户域模型,它不应该。

于 2012-07-25T12:44:03.007 回答
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");
}
于 2012-07-25T12:40:55.967 回答