harmeet
harmeet

Reputation: 137

HttpContext.Current is null after Task.Run

Here are my project details

  1. A web-API project containing webapi controllers
  2. I have a separate c# Library project that contains models for my webapi and some method and api for intracting with database.

settings in webconfig

 <httpRuntime targetFramework="4.5"/>
  <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>

Issue: HttpContext.Current.user is null.I want to access Httpcontext.Current.user in my c# library project.

1.In the code snippet below HttpContext.Current.user is available.This method exist in webapi project.

[HttpPost]
        public async Task<IHttpActionResult> Post([FromBody]TEntity entity)
        {
            System.Security.Principal.IPrincipal p = System.Threading.Thread.CurrentPrincipal;

            // context is available till here
            var context =HttpContext.Current.User;

            return await Task<IHttpActionResult>.Run(() =>
            {
                if (!ModelState.IsValid)
                {
                    return (IHttpActionResult)Content(HttpStatusCode.BadRequest, ModelState.ToUnexpectedResultWrapper());
                }

                try
                {
                    TOrchestrator orchestrator = new TOrchestrator();
                    orchestrator.Insert(entity);
                }
                catch (ValidationException ex)
                {
                    return Content(HttpStatusCode.BadRequest, ex.ToUnexpectedResultWrapper());
                }
                catch (DbEntityValidationException ex)
                {
                    return Content(HttpStatusCode.BadRequest, ex.ToUnexpectedResultWrapper());
                }

                return CreatedAtRoute("REST", new { id = entity.Id }, entity);
            });

        }

2.In code snippet below that exist in C# library. HttContext.Current.user is null. this method is called from the above method "Post".

 public void Insert(Market market)
            {
                // Context is 
                System.Security.Principal.IPrincipal p = System.Threading.Thread.CurrentPrincipal;
                //IOATIApplicationUser user = UserContextHelper.GetOATIContext().OATIUser;
                var http = HttpContext.Current.User;
                RunAction<InsertAction, Market>(market);
            }

More over I could access user object from System.Threading.Thread.CurrentPrincipal.

If I cant access user object from HttpContext. Can i user System> System.Threading.Thread.CurrentPrincipal. I have heard it is not safe to user "System.Threading.Thread.CurrentPrincipal" and it is ment for window forms only.

Upvotes: 4

Views: 4510

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 457332

HttpContext.Current returns the current HttpContext being serviced by the calling thread. When you start a background task by using Task.Run, it is not associated with an HTTP context by design.

Since you should not be using Task.Run on ASP.NET anyway, removing it is the easiest solution:

[HttpPost]
public IHttpActionResult Post([FromBody]TEntity entity)
{
  if (!ModelState.IsValid)
  {
    return (IHttpActionResult)Content(HttpStatusCode.BadRequest, ModelState.ToUnexpectedResultWrapper());
  }

  try
  {
    TOrchestrator orchestrator = new TOrchestrator();
    orchestrator.Insert(entity);
  }
  catch (ValidationException ex)
  {
    return Content(HttpStatusCode.BadRequest, ex.ToUnexpectedResultWrapper());
  }
  catch (DbEntityValidationException ex)
  {
    return Content(HttpStatusCode.BadRequest, ex.ToUnexpectedResultWrapper());
  }

  return CreatedAtRoute("REST", new { id = entity.Id }, entity);
}

Upvotes: 3

Related Questions