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添加到Controller的ControllerContext中。 我发现HttpContext.Current是null但是Controller的Session [] 不是null,因为它来自Controller的ControllerContext。 那么在模拟请求时我该怎么做才能避免HttpContext.Current为null
答案 0 :(得分: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);
}
编辑(回答评论中的问题):
要获得会话,您需要致电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
是一个键/值集合,可用于在HTTP请求期间在IHttpModule
接口和IHttpHandler
接口之间组织和共享数据。
您要求的语句,只是通过使用反射来创建一个新的HttpSessionState
对象(因为它只有内部构造函数)将它与您之前创建的HttpSessionStateContainer
相关联并将其存储在{在HttpContext.Items
下{1}}。有趣的是AspSession
实际上是HttpContext.Current.Session
的捷径。因此,将HttpSessionState对象赋值给HttpContext.Items["AspSession"]
键是使AspSession
起作用的基础。
答案 1 :(得分:1)
好吧,在嘲笑HttpContext后,Alex Art说道。
调用以下方法即可。
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
));