Search code examples
c#asp.net-mvcviewbag

Accessing ViewBag variables in View


Finally giving up on asking the Google Gods...

I'm trying to access ViewBag variables in my view from the query below.

using (var context = new PrincipalContext(ContextType.Domain))
{
    var un = UserPrincipal.FindByIdentity(context, User.Identity.Name);
    var userinfo = db.Users
                     .Where(x => x.sAMAccountName == un.SamAccountName)
                     .Select(x => new
                      {
                          x.sAMAccountName,
                          x.Id
                      }).First();

    ViewBag.UserInfo = userinfo;
}

I see the variables in VS' breakpoint watcher

enter image description here

However, when I try to access them:

enter image description here

enter image description here

Not 100% certain on how I'm supposed to be accessing these? I don't want to iterate through them because they're getting placed in a form as fields. As previously mentioned, the Google Gods were less than helpful. Thanks!

UPDATE

I took a closer look based on the responses received, regarding casting. Ultimately what I ended up doing was retrieving the entire model and returning that in the ViewBag, and accessing it as such:

using (var context = new PrincipalContext(ContextType.Domain))
{
     var un = UserPrincipal.FindByIdentity(context, User.Identity.Name);
     User info = new User();
     info = (User)db.Users
                .Where(x => x.sAMAccountName == un.SamAccountName)
                .First();
      ViewBag.User = info;

}

And then in the view

@ViewBag.User.Id
@ViewBag.User.sAMAccountName

Ultimately I was looking to access these variables without iterating over them in a loop. When I add a select statement into my query, it begins to complain that I'm trying to cast anonymous strings to a model object. Is one able to retrieve select data from a model in ASP, or do you need to return an entire model set? Now it's just curiosity. Thank you for the guidance!


Solution

  • With anonymous type object in ViewBag, you cannot access their properties just by using a . operator. That's because the anonymous type is generated as internal. So better approach would be to create a type with the desired properties, like so (say the type is called UserInfo). By creating a separate type that has just the properties needed for the view, you can optimize your query to select just those fields from the database (a common practice).

    ViewBag.UserInfo = db.Users
                         .Where(x => x.sAMAccountName == un.SamAccountName)
                         .Select(x => new UserInfo // the object is now of type UserInfo
                         {
                             sAMAccountName = x.sAMAccountName,
                             Id = x.Id
                         }).First();
    

    Then in view file you can access the properties with a cast like so:

    (UserInfo(ViewBag.UserInfo)).sAMAccountName
    

    Ugly way to access the properties with reflection in view file (don't do this):

    @{
        string name = ViewBag.UserInfo.GetType().GetProperty("sAMAccountName").GetValue(ViewBag.UserInfo) as string;
    }