2015-04-18 2 views
1
public async Task <ActionResult>Select(DWorkingTimeSelection dto) { 
    var session = HttpUtils.GetSeesion<User>("USER"); 
} 

public static T GetSeesion<T>(string key) where T : class 
{ 
    if (HttpContext.Current == null) 
    { 
     return default(T); 
    } 
    return HttpContext.Current.Session[key] as T; 
} 

public async Task <ActionResult>Select(DWorkingTimeSelection dto) { 
    var session = HttpUtils.GetSeesion<User>("USER"); 
} 

public static T GetSeesion<T>(string key) where T : class 
{ 
    if (HttpContext.Current == null) 
    { 
     return default(T); 
    } 
    return HttpContext.Current.Session[key] as T; 
} 

Я использую nunti для издевательства над запросом. И я добавляю SessionStateItemCollection к ControllerContext контроллера. Я обнаружил, что HttpContext.Current является нулевым, но сеанс контроллера [] не является нулевым, потому что он получен из ControllerContext контроллера. Так что я должен сделать, чтобы избежать HttpContext.Current является недействительным, а насмешливый запросASP.NET MVC, HttpContext.Current является нулевым, если насмехается с запросом

ответ

1

Вы можете дразнить HttpContext:

public static HttpContext FakeHttpContext(HttpRequest request) 
    { 
     var stringWriter = new StringWriter(); 
     var httpResponce = new HttpResponse(stringWriter); 
     var httpContext = new HttpContext(request, httpResponce); 

     var sessionContainer = new HttpSessionStateContainer(
      "id", 
      new SessionStateItemCollection(), 
      new HttpStaticObjectsCollection(), 
      10, 
      true, 
      HttpCookieMode.AutoDetect, 
      SessionStateMode.InProc, 
      false); 

     httpContext.Items["AspSession"] = 
      typeof(HttpSessionState).GetConstructor(
       BindingFlags.NonPublic | BindingFlags.Instance, 
       null, 
       CallingConventions.Standard, 
       new[] { typeof(HttpSessionStateContainer) }, 
       null).Invoke(new object[] { sessionContainer }); 

     return httpContext; 
    } 

    [TestMethod] 
    public void ActionTest() 
    { 
     var request = new HttpRequest(string.Empty, "url to the action that you are testing", string.Empty) 
     { 
      RequestType = "GET" 
     }; 
     HttpContext.Current = FakeHttpContext(request); 

     var controller = new YourController(); 
     //You need the get a Result property since it is an async action 
     var result = controller.ActionToTest(//the parameters that your action expects).Result; 
     Assert.IsNotNull(result); 
    } 

EDIT (отвечая на вопросы в своем комментарии):

Чтобы получить сеанс, вам нужно позвонить HttpContext.Current.Session, а не HttpContext.Current.Session["id"], потому что HttpContext.Current.Session["id"] пытается получить ключ id из вашей сессии. После того, как вы его сохраните, он будет доступен через этот звонок. Вы можете проверить это:

HttpContext.Current.Session["id"] = 5; 
Assert.AreEqual(HttpContext.Current.Session["id"],5); 

Что касается httpContext.Items заявления:

(Из MSDN) HttpContext.Items представляет собой набор ключ/значение, которое может быть использовано для организации и обмена данными между IHttpModule интерфейсом и интерфейсом IHttpHandler во время HTTP-запрос.

Утверждение, что вы просите, просто ящики нового HttpSessionState объекта с помощью отражения (потому что он имеет только внутренние конструктор) связывает его с HttpSessionStateContainer, который вы создали ранее и сохраняет его в HttpContext.Items под AspSession. И интересно, что HttpContext.Current.Session на самом деле является ярлыком для HttpContext.Items["AspSession"]. Таким образом, назначение объекта HttpSessionState на ключ AspSession - это то, что делает работу HttpContext.Current.Session.

+0

Ну, теперь HttpContext.Current не является нулевым .Но я не могу получить сеанс от HttpContext.Current.Session [ «ID»] еще .И могли бы вы объяснить, что эффект от заявления - httpContext.Items, пожалуйста? – Zeurso

+0

См. Последние изменения. Если бы мой ответ был полезен и решил вашу проблему, пожалуйста, отметьте его как aswer –

+0

О, большое вам спасибо! – Zeurso

1

Ну, издеваясь над HttpContext, как сказал Алекс Арт.

Вызов следующего метода будет прекрасным.

var sessionItems = new SessionStateItemCollection(); 
     sessionItems["SessionKey"] = new MyCustomObject(); 
     SessionStateUtility.AddHttpSessionStateToContext(fakeHttpContext, 
      new HttpSessionStateContainer(SessionNameStorage.Suser, 
          sessionItems, 
          new HttpStaticObjectsCollection(), 
          20000, 
          true, 
          HttpCookieMode.AutoDetect, 
          SessionStateMode.InProc, 
          false 
        )); 
Смежные вопросы