0

I want to get the UserName of the currently logged in User. But when I used User.Identity.Name I got following error:

System.NullReferenceException. Object reference not set to an instance of an object.

The code where I am getting the error is as follows:

UsersConfigurationController qr = new UsersConfigurationController();
        public ActionResult Create(FormCollection collection)
        {
            try
            {
                context.Roles.Add(new Microsoft.AspNet.Identity.EntityFramework.IdentityRole()
                {
                    Name = collection["RoleName"]
                });
                context.SaveChanges();
                qr.singleRoleAddToDb(collection["RoleName"]);
                ViewBag.ResultMessage = "Role created successfully !";
                return RedirectToAction("Create");
            }
            catch
            {
                return View();
            }
        }

The error occurs when the following line is executed:

qr.singleRoleAddToDb(collection["RoleName"]);

The function singleRoleAddToDb resides in UserConfigurationController as follows:

public void singleRoleAddToDb(string rolename)
        {
            UserRoles urls = new UserRoles();
            urls.S1 = rolename;
            urls.S2 = HttpContext.User.Identity.Name;
            urls.N102 = db.Users.Where(x => x.S1 == HttpContext.User.Identity.Name).Single().N102;
            db.UserRoles.Add(urls);
            db.SaveChanges();

        }  

As soon as the line urls.S2 = HttpContext.User.Identity.Name; executes the debugger switches to Catch statement and throws the above mentioned erro. I have already tried to change the authentication mode in config file:

<authentication mode="Forms" />

and also

<authentication mode="Windows" />

But the error continues.

Awais Mahmood
  • 1,268
  • 4
  • 21
  • 45
  • @DanielKelley, I know about this error.. But here I am unable to get the point why this error is occurring for User.Identity.Name – Awais Mahmood Sep 08 '15 at 10:42
  • Why not using UserManager to get UserName of Logged in user? – Anup Sharma Sep 08 '15 at 10:43
  • set your breakpoints, and see where the error is thrown. – user1666620 Sep 08 '15 at 10:44
  • Which property is `null`? `HttpContext` or `User` or `Identity`? –  Sep 08 '15 at 10:45
  • @StephenMuecke, Name is empty.. – Awais Mahmood Sep 08 '15 at 10:52
  • @user1666620, when setting the property urls.S2 = HttpContext.User.Identity.Name; – Awais Mahmood Sep 08 '15 at 10:53
  • The `Name` being empty (`null`) will NOT throw an exception. Either `HttpContext` or `User` or `Identity` is `null` - debug your code –  Sep 08 '15 at 10:54
  • As a sanity check - is the user actually logged in when this method is called? – user1666620 Sep 08 '15 at 10:56
  • @StephenMuecke, kindly see this image.. it has the screenshot for my identity property in debugging mode. [link](http://imgur.com/Sx0ZkSn) – Awais Mahmood Sep 08 '15 at 11:00
  • @Shaamaan, User is obviously logged in.. That would be the first thing I would check. and I already did. The application is saying Hello to the user after successful logging in – Awais Mahmood Sep 08 '15 at 11:02
  • @AwaisMahmood Looking at your screenshot - first, the user isn't logged in (`IsAuthenticated` is false), but `HttpContext.User.Identity` isn't null and `Name` is just an empty string. Then I suspect your `db` object might not exist. `db` is not assigned anywhere the code you've shown, so it's difficult to say if that's the problem or not. – Shaamaan Sep 08 '15 at 11:03
  • @AwaisMahmood, You have shown an image that is not the same as the code in your question. `urls.S2 = HttpContext.User.Identity.Name;` cannot throw an exception just because `Name` is an empty string. –  Sep 08 '15 at 11:05
  • @StephenMuecke, check the edit.. Sorry for not mentioning the complete code. I thought that it wont be needed. – Awais Mahmood Sep 08 '15 at 11:15
  • Looking at the question after the edit - something doesn't add up. In your screenshot `HttpContext.User.Identity` isn't null and `Name` is an empty string. But you say the error is thrown on `urls.S2 = HttpContext.User.Identity.Name;`, and `urls` has just been created. Either for some strange reason `HttpContext` isn't *kept* between functions, or you're looking at wrong code (this can happen if you're looking at newer code than was used in the DLLs loaded by IIS). – Shaamaan Sep 08 '15 at 11:22
  • 1
    What does `string name = HttpContext.User.Identity.Name;` return? Is property `S2` of `UserRoles` a simple get/set or is there some code in the setter? –  Sep 08 '15 at 11:23
  • Can you post complete exception stacktrace? `db.Users.Where(x => x.S1 == HttpContext.User.Identity.Name)` might returning empty collection, so `.Single().N102` throw exception. – Mukesh Modhvadiya Sep 08 '15 at 11:29
  • 1
    @Mark Unless `Users` is null, then `Single` won't throw a null-reference error. `Single` will inform if the collection contains no elements or too many elements in a more informative manner. – Shaamaan Sep 08 '15 at 11:33
  • @StephenMuecke, simple get/set.. Actually, when debugger reaches at line **urls.S2 = HttpContext.User.Identity.Name;**, it jumps to the **Catch** block. So, I cannot see which is null – Awais Mahmood Sep 08 '15 at 11:34
  • @Mak, when debugger reaches at line urls.S2 = HttpContext.User.Identity.Name;, it jumps to the Catch block. so the error whatever causing it, occurs before db execution – Awais Mahmood Sep 08 '15 at 11:36
  • Can you add more code to the application and see what happens? Add the following to the start of `singleRoleAddToDb`: `if (HttpContext == null) throw new ArgumentNullException("HttpContext"); if (HttpContext.User == null) throw new ArgumentNullException("HttpContext.User"); if (HttpContext.User.Identity == null) throw new ArgumentNullException("HttpContext.User.Identity");` and so on as needed... Do that, and you should get better indication of what is null. – Shaamaan Sep 08 '15 at 11:37
  • @AwaisMahmood, Just add `string name = HttpContext.User.Identity.Name;` before the `try` block and inspect the values –  Sep 08 '15 at 11:40
  • 1
    @Shaamaan, when I added your mentioned codes at start of **singleRoleAddToDb** it is observed that **HttpContext** is null in that controller. – Awais Mahmood Sep 08 '15 at 11:44
  • @StephenMuecke, when I added user.identity.name before try block, it successfully gets the user name.. But in the other controller where **singleAddToDb** resides **HttpContext** is null – Awais Mahmood Sep 08 '15 at 11:45
  • 1
    Well, there's your answer then. Modify the method to accept the identity as a parameter, and pass that where needed. `public void singleRoleAddToDb(string rolename, string identityName) {...}` – Shaamaan Sep 08 '15 at 11:46
  • @StephenMuecke, Thank you very much for this long discussion. But can you tell why HttpContext is null in the other controller???. Thanks again – Awais Mahmood Sep 08 '15 at 11:49
  • Without looking at your entire code I cannot tell. If I were to make a wild guess it would be because it's called from a different DLL and might simply not have access to `HttpContext`. But, again, wild guessing here! – Shaamaan Sep 08 '15 at 11:52
  • Are your saying the `Create()` and `singleRoleAddToDb()` methods are in separate controllers? If so then of course `HttpContext.User` will be `null` –  Sep 08 '15 at 11:52
  • @StephenMuecke, Yes, they are in different controllers.. But isn't the **HttpContext** values available in entire application? I mean if I want to get UserName in any other controller I can simply get it by **HttpContext** – Awais Mahmood Sep 08 '15 at 11:56
  • 1
    @Shaamaan, all the controllers are called from 1 DLL... So, How can the DLL is different?? – Awais Mahmood Sep 08 '15 at 11:57
  • Well, a quick Google shows [this](http://stackoverflow.com/questions/19509672/why-httpcontext-current-be-null) result. I don't know if it's relevant here or not. – Shaamaan Sep 08 '15 at 11:58
  • No they are not. The `HttpContext` is generated from the request, and `User` properties from its `cookies` (which don't exist in your other controller because its not called from a request) –  Sep 08 '15 at 12:01
  • @StephenMuecke, THANKS a lot man, You really solved my problem.. – Awais Mahmood Sep 08 '15 at 12:09

1 Answers1

0

If for some reason you cannot use a debugger to catch the code and inspect the variables you can try this old trick...

Add the following code to the start of singleRoleAddToDb method to check what exactly is null:

if (HttpContext == null) 
  throw new ArgumentNullException("HttpContext");
if (HttpContext.User == null) 
  throw new ArgumentNullException("HttpContext.User"); 
if (HttpContext.User.Identity == null) 
  throw new ArgumentNullException("HttpContext.User.Identity");

Depending on what turns out to be missing you may need to pass that as an additional parameter.

Shaamaan
  • 4,805
  • 1
  • 37
  • 66
  • 2
    This helped me in finding an answer.. Actually HttpContext was null because singleRoleAddToDb method was not called from the user request – Awais Mahmood Sep 08 '15 at 12:10