0

i'm having some problems with to pass value from UserProfile to @Viewbag to show in Index.cshtml.

Let's explain:

When i'm do a Register of new user or Login, i'm trying to pass UserType field from UserProfile in a viewbag. UserType is a custom field that i create on UserProfile to validate if the user is a "Musico" or "Ouvinte"

After debug application, I see that viewbag is taking NULL value.

This is the code that i try to get value from UserProfile in Register and Login post method:

LOGIN POST METHOD

[HttpPost] 
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
    if (ModelState.IsValid && WebSecurity.Login(model.UserName,
                                                model.Password,
                                                persistCookie: model.RememberMe))
    {
        var context = new UsersContext();
        var username = User.Identity.Name;
        var user = context.UserProfiles.SingleOrDefault(u => u.UserName == username);
        var userType = user.UserType;

        TempData["UserType"] = userType; //Taking UserType from User Profile
        return RedirectToLocal(returnUrl);
    }

    // If we got this far, something failed, redisplay form
    ModelState.AddModelError("", "The user name or password provided is incorrect.");
    return View(model); 
}

REGISTER POST METHOD

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
    if (ModelState.IsValid)
    {
        // Attempt to register the user
        try
        {
            var context = new UsersContext();
            var username = User.Identity.Name;
            var user = context.UserProfiles
                              .SingleOrDefault(u => u.UserName == username);
            var userType = user.UserType;
            WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new
            {
                UserType = model.UserType
            });
            WebSecurity.Login(model.UserName, model.Password);

            // string currentUserType = u.UserType;                    
            TempData["UserType"] = userType;//Get the userType to validate on _Layout
            return RedirectToAction("Index", "Home");
        }
        catch (MembershipCreateUserException e)
        {
            ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
        }
    }
    return View(model);
}

Calling viewbag in part of Index page

<p>
@if (Request.IsAuthenticated && ViewBag.UserType.Equals("Musico")) 
         {
              <span>musico</span>
         }
         else if (Request.IsAuthenticated && ViewBag.UserType.Equals("Ouvinte"))
         {
             <span>ouvinte</span>
         } else{
          <span>teste</span>
         }
</p>

HomeController

public ActionResult Index()
{
    ViewBag.UserType = TempData["UserType"];
    return View();
}
Pedro Henrique
  • 547
  • 1
  • 8
  • 24
  • @Silvermind Can you post an example of this? Sorry i don't understand your idea – Pedro Henrique Oct 11 '14 at 19:55
  • Take a look on Index.cshtml The first time that i run the application, "teste" is displayed on page. After i logged in application, with breakpoint on index, the value is null, I'll put a screen http://imgur.com/upOyyq7 – Pedro Henrique Oct 11 '14 at 20:51
  • When I make a login, the index always return "Teste" – Pedro Henrique Oct 11 '14 at 21:16
  • Yes, I do this changes. When I'll register a new user, the following error is displayed on this line: **var userType = user.UserType;** `System.NullReferenceException: Object reference not set to an instance of an object.` And I can do a Login, but "teste" is displayed on Index. And in debug, I can take the field UserName, but not UserType. – Pedro Henrique Oct 11 '14 at 21:27
  • For the first remark see: [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/q/4660142/858757) For your second remark: UserType is not set in the database when UserName does work and UserType does not. – Silvermind Oct 11 '14 at 21:35
  • I'll read this article. And UserType are setup in my Database http://imgur.com/fdLVTSi – Pedro Henrique Oct 11 '14 at 21:38
  • To be more clear with you, maybe you can add me in skype and I can share my screen with you. If you think that is a good idea my skype is pedrro.1 – Pedro Henrique Oct 11 '14 at 21:47
  • About UserType, That is not what I mean. I believe you if you say the column exists, but I am asking: Is the value inside the column `NULL`? – Silvermind Oct 11 '14 at 21:47
  • No, the value always be "Musico" or "Ouvinte". I think that the problem is how I have to take the UserType from actual user logged on application, what do you think? – Pedro Henrique Oct 11 '14 at 21:52
  • Well, I think you will just have to debug that part. – Silvermind Oct 11 '14 at 21:54
  • Yeah, I don't know how is the correct way to do this... :( If you look on Login and Register method, you can seed that i'm trying to take the UserType information with 2 ways, and anyone is working correctly – Pedro Henrique Oct 11 '14 at 21:56
  • @Silvermind I do the debug and create other post only to ask about the Login, could you take a look on it? http://stackoverflow.com/questions/26328660/how-to-get-custom-information-from-userprofile – Pedro Henrique Oct 12 '14 at 20:14

2 Answers2

2

See this article for a good explanation, When to use ViewBag, ViewData, or TempData.

.. once the controller redirects, the ViewBag and ViewData will contain null values. If you inspect the TempData object with debugging tools after the redirect you'll see that it is fully populated.

Do this instead:

TempData["UserType"] = userType;

Change your view accordingly i.e.

@{var tempUserType = TempData["UserType"]} // in the top

And then use it as you would with the ViewBag

brk
  • 1,216
  • 1
  • 15
  • 22
  • Hi @Twice could you take a look on the issue displayed on comments of question? Thank you – Pedro Henrique Oct 11 '14 at 21:43
  • @PedroHenrique how are you accessing the TempData in your View? – brk Oct 11 '14 at 22:01
  • Yes, I tried, here the example that i put on my view: `@if (Request.IsAuthenticated && TempData["UserType"]=="Musico") { musico } else if (Request.IsAuthenticated && TempData["UserType"] == "Ouvinte") { ouvinte } else{ teste }` – Pedro Henrique Oct 11 '14 at 22:08
  • @PedroHenrique try `TempData["UserType"] = "User type 123";` then in the redirected action you could `ViewBag.UserType = TempData["UserType"];` and in your view `@if (TempData["UserType"] == "User type 123"){//do something}`. This should work. In your case I suspect, that it's because your `userType` is null and that's why it doesn't work. Debug and see if that's the case. – brk Oct 12 '14 at 08:45
  • In my debug, I identify that the problem is on var currentUser in Login method, It isn't taken the user. I created another post to ask about this, could you take a look on it? http://stackoverflow.com/questions/26328660/how-to-get-custom-information-from-userprofile thank you – Pedro Henrique Oct 12 '14 at 20:16
1

The ViewBag is lost because of the redirect. An easy solution would be to use TempData, which only remains valid after one extra request. After that, it is normally gone, there is however a Keep method.

From MSDN:

However, the data in a TempDataDictionary object persists only from one request to the next, unless you mark one or more keys for retention by using the Keep method. If a key is marked for retention, the key is retained for the next request.

Example:

[Authorize]
public class AccountController : Controller
{
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Register(RegisterModel model)
    {
        if (ModelState.IsValid)
        {
            // do stuff
            TempData["UserType"] = userType;
            return RedirectToAction("Index", "Home");
        }
        // something went wrong, return view
        return View(model);
    }
}

[Authorize]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.UserType = TempData["UserType"];
        return View();
    }
}
Silvermind
  • 5,271
  • 2
  • 21
  • 39
  • Thanks @Silvermind, I update my code to use the TempData, but, when I'll run the application, The index are showing that viewbag have a null value :( I need to update something at view? – Pedro Henrique Oct 11 '14 at 20:23
  • Can you add your changes to your question? – Silvermind Oct 11 '14 at 20:28
  • Done! @Silvermind The exception displayed after login/register is "Exception: Cannot perform runtime binding on a null reference" – Pedro Henrique Oct 11 '14 at 20:32