2

I am using the following code for sign in in a web api. I get null reference exception on FormsAuthentication.SetAuthCookie(authUser.UserId.ToString(), false); call. Please guide me what I am doing wrong...

[AllowAnonymous]
    [HttpPost]
    public async Task<string> SignIn(JObject credentails)
    {
        string returnVal = "";

        await Task.Run(() =>
        {
            string userName = (string)credentails.SelectToken("Username");
            string password = (string)credentails.SelectToken("Password");
            UserService userSvc = new UserService(new SqlConnection(_conStr));
            var authUser = userSvc.Authenticate(userName, password);
            if (authUser != null)
            {
                FormsAuthentication.SetAuthCookie(userName, false);
                HttpContext.Current.Session.Add("DR_CLIENT_ID", authUser.DRClientId);
                HttpContext.Current.Session.Add("USER_ID", authUser.UserId);
                returnVal = authUser.FullName;
            }
            else
            {
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
                {
                    Content = new StringContent("Invalid Credentials!"),
                    ReasonPhrase = "Error"
                });
            }
        });
        return returnVal;
    }

UPDATE-1 in this case no value is actually null as I can see it in the debug mode. but when I remove wait Task.Run(() = {}); block from this code, it works fine without any issue.

Leo
  • 23
  • 4
  • please re-consider as this question is not about null reference exception and is about main thread and background thread... – Leo Nov 26 '14 at 12:10
  • Okay. Next time, please make clear you checked all this. I was not able to tell from your question. Also, if there is one close voter, use @username to ping him. – Patrick Hofman Nov 26 '14 at 12:15
  • 1
    `HttpContext.Current` will be null inside the task, which is probably the reason for your NullReferenceException. See [this question](http://stackoverflow.com/questions/13748267/using-httpcontext-in-async-task) – Daniel J.G. Nov 26 '14 at 12:18
  • @DanielJ.G. it does not seems to be null in debug mode. – Leo Nov 26 '14 at 12:20
  • FYI no body seemed to have addressed the elephant in the room . Why would you use Task.Run for this in the first place. even if you were not using SetAuthCookie you will still wan't your web app to be I/O bound. UserService which reaches out to be DB should be in implemented in an asynchronous manner and nothing else in that code has any reason to be done on another thread. – eran otzap Oct 13 '16 at 18:47

1 Answers1

4

The problem is Task.Run. In ASP.NET, when an incoming request arrives, it assigns a thread pool thread to handle that request, and this thread runs your code. What your code then does is use Task.Run to move to another thread pool thread without a request context, and then assumes it has a request context. FormsAuthentication.SetAuthCookie (and HttpContext.Current) will simply not work without a request context.

To resolve this, remove the call to Task.Run. You should (almost) never use Task.Run on ASP.NET.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810