Work with null HttpContext.Current when starting the application, if the user already has a cookie

I am developing a web project that contains an authorization system that uses cookies. I am using Identity 2.0 Sample Project, so I have a built-in function. I also use Git as my version control system.

I merged the two branches. Both of them work easily with authorization and cookies. When you log in and then stop the application through Visual Studio, I can start the application again and I remain in the system.

After I merged the two branches, I got some strange behavior. The code I combined does not affect the authorization system.

When you enter the cookie, it is created, so when I manually stop the application through Visual Studio and then run it again, I have to log in. The application crashes with the following exception:

An exception of type 'System.NullReferenceException' occurred in Microsoft.Owin.Host.SystemWeb.dll but was not handled in user code 

And Visual Studio points to the following line:

  var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); 

Code was included in the Identity Sample, and it worked just fine before merging. As I found out, if I delete the following piece of code, the application works fine; I can stop it and restart with zero exceptions:

  @{ var manager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); var currentUser = manager.FindById(User.Identity.GetUserId()); } @Html.ActionLink("Hello " + currentUser.UserNickName + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" }) 

This code is part of the _LoggingPartial View, which was modified by Visual Studio and modified in the I branch merged with.

So now I am completely lost because I don’t know what caused this exception.

Perhaps someone can help me, give advice on how I can solve it.

UPDATE:

As I understand it, the problem is not a nickname. In fact, the application crashes after stopping, even if I add the following code to the old vesrion:

  @{ var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); var currentUser = userManager.FindById(User.Identity.GetUserId()); } @Html.ActionLink("Hello " + currentUser.Email.ToString() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" }) 

As you can see, this code does not use any methods except built-in identifiers.

In addition, I tested various methods to get the user and got the following results:

The application fails if I use 'var currentUser = userManager.FindById (User.Identity.GetUserId ());

The application fails if I use 'var currentUser = userManager.FindByIdAsync (User.Identity.GetUserId ()); (Of course, I changed the rest of the code to work with the async result)

The application fails if I use 'var currentUser = userManager.FindByName (User.Identity.GetUserName ());

The application does not crash if I use 'var currentUser = userManager.FindByNameAsync (User.Identity.GetUserName ());

Thus, it does not work with FindById and with FindByIdAsync. If I use FindByName, it works with FindByNameAsync, but crashes with a simple FindByName

+5
source share
1 answer

I found out the cause of the error. When we log in, our user information is stored in cookies. Since we are using the Id string (default in Identity), userId = someRandomHash (). Perhaps not by chance, but it is not permanent. So, we have randomString1 in our cookies. When we stop the server and start it again, the database is generated again, because our database initialization is defined as "DropCreateAlways". Therefore, in our database randomString2, but randomString1 in cookies. When we try to get the saved identifier from cookies, we get it successfully, but we cannot find it in the database using userManager, since Id is now different.

In addition, this explains why the error cannot be reproduced using the GetName () method - we always have the same username. And it only works with async Find (), because it starts when we still have the database. However, a simple async method is executed when db is already dropped and we don't have a name. I still don’t know why Visual Studio pointed to the line "var userManager", but I think this is not very important.

+1
source

Source: https://habr.com/ru/post/1206030/


All Articles