在Task.Run之后,HttpContext.Current为null

时间:2015-07-13 16:54:41

标签: asp.net asynchronous asp.net-web-api task

以下是我的项目详情

  1. 包含webapi控制器的Web-API项目
  2. 我有一个单独的c#Library项目,其中包含我的webapi模型以及一些用于与数据库进行交互的方法和api。
  3. webconfig中的设置

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

    问题:HttpContext.Current.user为null。我想访问我的c#库项目中的Httpcontext.Current.user。

    1.在下面的代码片段中,HttpContext.Current.user可用。此方法存在于webapi项目中。

    [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.在C#库中存在的下面的代码片段中。 HttContext.Current.user为null。从上面的方法“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);
                }
    

    此外,我可以从System.Threading.Thread.CurrentPrincipal访问用户对象。

    如果我无法从HttpContext访问用户对象。我可以用户系统&gt; System.Threading.Thread.CurrentPrincipal。我听说用户“System.Threading.Thread.CurrentPrincipal”是不安全的,只适用于窗体。

1 个答案:

答案 0 :(得分:3)

HttpContext.Current返回由调用线程提供服务的当前HttpContext。使用Task.Run启动后台任务时,它与设计的HTTP上下文无关。

既然你不应该在ASP.NET上使用Task.Run,删除它是最简单的解决方案:

[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);
}