2015-07-13 3 views
1

Вот мои детали проектаHttpContext.Current является недействительным после Task.Run

  1. проекта веб-API, содержащие контроллеры WebAPI
  2. У меня есть отдельный C# библиотека проект, который содержит модели для моей WebAPI и каким-либо способом и api для работы с базой данных.

настройки в WebConfig

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

Выпуска: HttpContext.Current.user является null.I хочет получить доступ к 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. этот метод вызывается из вышеуказанного метода «Почта».

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. Может ли пользовательская система> System.Threading.Thread.CurrentPrincipal. Я слышал, что это не безопасно для пользователя «System.Threading.Thread.CurrentPrincipal», и это касается только оконных форм.

+2

'System.Threading.Thread.CurrentPrincipal' получает пользователь сайт работает, как, что часто не фактический пользователь, который обращается к сайту. Вместо того, чтобы использовать 'HttpContext.Current' для получения ваших данных, почему бы не передать его в свой метод' Insert' в качестве параметра? Библиотеки часто не должны зависеть от наличия доступного «HttpContext» и должны получать необходимую информацию через параметры, чтобы сохранить переносимый код. – mason

+0

спасибо масон. Это имеет смысл – harmeet

ответ

3

HttpContext.Current возвращает текущий HttpContext обслуживается вызывающей линией. Когда вы запускаете фоновое задание с помощью Task.Run, оно не связано с контекстом HTTP по дизайну.

Поскольку вы не должны использовать Task.Run на ASP.NET в любом случае, удаление это самое простое решение:

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

Стивен благодарит за ответ. мы разрабатываем фреймворк, и нам нужно выставить текущий принцип, доступный во всех потоках. Над фрагментом кода находится команда приложения. Мы не сможем изменить импланирование. . Можно ли использовать System.Threading.Thread.CurrentPrincipal.Value принципала не является нулевым даже в Task.Run. – harmeet

+0

@harmeet: Если ваша инфраструктура должна раскрывать контекст, я рекомендую сделать это через фактический * контекстный экземпляр *, а не какой-либо TLS или окружающее состояние. Но если вам нужно, то 'Thread.CurrentPrincipal' должен работать. –

+0

Я не получил то, что вы имели в виду под TLS или окружающим состоянием. Моя цель только в том, что если я получаю доступ к Thread, currentPrincipal должен возвращать принципалу, который в настоящее время зарегистрирован в принципе пользователя. – harmeet

Смежные вопросы