![](/img/trans.png)
[英]Cannot access Session object inside a helper class within my Asp.Net Core project
[英]Cannot access session asp.net core
嗨,請幫助我嘗試在 asp.net core 中測試會話,但是當我設置會話並從其他控制器獲取它時,它似乎為空
這是我的創業公司
public class Startup
{
public IConfigurationRoot Configuration { get; }
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc().AddJsonOptions(options => {
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
});
// Adds a default in-memory implementation of IDistributedCache.
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
// Set a short timeout for easy testing.
options.IdleTimeout = TimeSpan.FromSeconds(600);
options.CookieHttpOnly = true;
});
services.AddSingleton<IConfiguration>(Configuration);
services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();
services.AddTransient<IApiHelper, ApiHelper>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseSession();
app.UseDeveloperExceptionPage();
if (env.IsDevelopment())
{
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions {
HotModuleReplacement = true,
ReactHotModuleReplacement = true
});
}
//var connectionString = Configuration.GetSection("ConnectionStrings").GetSection("ClientConnection").Value;
app.UseStaticFiles();
loggerFactory.AddConsole();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
}
public static void Main(string[] args) {
var host = new WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseKestrel()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
這是我如何設置會話
public class HomeController : Controller
{
public IActionResult Index()
{
HttpContext.Session.SetString("Test", "Ben Rules!");
return View();
}
public IActionResult Error()
{
return View();
}
}
這里是我再次獲取會話的示例代碼,但它似乎為空
[HttpGet("[action]")]
public IEnumerable<JobDescription> GetJobDefinitions()
{
//this is always null
var xd = HttpContext.Session.GetString("Test");
var x = _apiHelper.SendRequest<Boolean>($"api/JobRequest/GetJobRequest",null);
var returnValue = new List<JobDescription>();
returnValue = jobDescriptionManager.GetJobDescriptions();
return returnValue;
}
感謝您的幫助
對於VS2017
,請遵循有關ASP.NET Core 中的會話和應用程序狀態的MSDN 官方文章。 您可以在我創建的以下示例中測試您的場景。 注意:雖然下面的代碼看起來很長,但實際上,您只會對從默認 ASP.NET Core 模板創建的默認應用程序進行一些細微的更改。 只需按照以下步驟操作:
使用VS2017
默認模板創建 ASP.NET Core MVC 應用程序
修改默認的Home controller
如下圖
確保Startup.cs
文件具有會話相關條目,如下面的Startup.cs
文件所示
運行應用程序並單擊頂部欄上的Home
鏈接。 這將存儲如下所示的會話值( Nam Wam
2017
和current date
)
單擊頂部欄上的“ About
鏈接。 您會注意到會話值已傳遞給About
控制器。 但是我知道這不是您的問題,因為這僅測試將會話值傳遞給same
控制器上的另一個操作。 因此,要回答您的問題,請按照接下來的 3 個步驟操作。
創建另一個控制器AnotherController
- 如下所示 - 在Views\\Test
文件夾中使用新操作Test()
和 View Test.cshtml
在_Layout.cshtml
添加另一個鏈接<li><a asp-area="" asp-controller="Another" asp-action="Test">Test View</a></li>
右后<li>...Contact...</li>
鏈接如下圖
再次運行該應用程序並首先單擊頂部欄上的Home
鏈接。 然后單擊頂部欄上的Test
鏈接。 您會注意到會話值從HomController
傳遞到AnotherController
並成功顯示在Test
視圖上。
家庭控制器:
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
namespace MyProject.Controllers
{
public class HomeController : Controller
{
const string SessionKeyName = "_Name";
const string SessionKeyFY = "_FY";
const string SessionKeyDate = "_Date";
public IActionResult Index()
{
HttpContext.Session.SetString(SessionKeyName, "Nam Wam");
HttpContext.Session.SetInt32(SessionKeyFY , 2017);
// Requires you add the Set extension method mentioned in the SessionExtensions static class.
HttpContext.Session.Set<DateTime>(SessionKeyDate, DateTime.Now);
return View();
}
public IActionResult About()
{
ViewBag.Name = HttpContext.Session.GetString(SessionKeyName);
ViewBag.FY = HttpContext.Session.GetInt32(SessionKeyFY);
ViewBag.Date = HttpContext.Session.Get<DateTime>(SessionKeyDate);
ViewData["Message"] = "Session State In Asp.Net Core 1.1";
return View();
}
public IActionResult Contact()
{
ViewData["Message"] = "Contact Details";
return View();
}
public IActionResult Error()
{
return View();
}
}
public static class SessionExtensions
{
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T Get<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
}
}
}
About.cshtml [顯示來自same
控制器的會話變量值]
@{
ViewData["Title"] = "ASP.Net Core !!";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<table class="table table-responsive">
<tr>
<th>Name</th>
<th>Fiscal Year</th>
</tr>
<tr>
<td>@ViewBag.Name</td>
<td>@ViewBag.FY</td>
</tr>
</table>
<label>Date : @(ViewBag.Date.ToString("dd/MM/yyyy") != "01/01/0001" ? ViewBag.Date.ToString("dd/MM/yyyy") : "")</label>
AnotherController [A不同的控制器比HomeController中]:
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
public class AnotherController : Controller
{
const string SessionKeyName = "_Name";
const string SessionKeyFY = "_FY";
const string SessionKeyDate = "_Date";
// GET: /<controller>/
public IActionResult Test()
{
ViewBag.Name = HttpContext.Session.GetString(SessionKeyName);
ViewBag.FY = HttpContext.Session.GetInt32(SessionKeyFY);
ViewBag.Date = HttpContext.Session.Get<DateTime>(SessionKeyDate);
ViewData["Message"] = "Session State passed to different controller";
return View();
}
}
Test.cshtml : [顯示從主控制器傳遞到Another
控制器的會話變量值]
@{
ViewData["Title"] = "View sent from AnotherController";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<table class="table table-responsive">
<tr>
<th>Test-Name</th>
<th>Test-FY</th>
</tr>
<tr>
<td>@ViewBag.Name</td>
<td>@ViewBag.FY</td>
</tr>
</table>
<label>Date : @(ViewBag.Date.ToString("dd/MM/yyyy") != "01/01/0001" ? ViewBag.Date.ToString("dd/MM/yyyy") : "")</label>
_Layout.cshtml :
....
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
<li><a asp-area="" asp-controller="Another" asp-action="Test">Test View</a></li>
</ul>
</div>
....
Startup.cs :[確保您包含一些與會話相關的條目。 很可能當您在 VS2017 中創建 ASP.NET Core MVC 應用程序時,這些條目已經存在。 但請確保。]
....
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//In-Memory
services.AddDistributedMemoryCache();
services.AddSession(options => {
options.IdleTimeout = TimeSpan.FromMinutes(1);//Session Timeout.
});
// Add framework services.
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
....
要在您的 MVC 應用程序中使用 Session,您必須: 安裝Microsoft.AspNetCore.Session
NuGet 包。
在Startup.cs
ConfigureServices
添加AddSession()
:
services.AddMvc();
services.AddSession(options => {
options.IdleTimeout = TimeSpan.FromHours(1);
});
在Startup.cs
配置中添加UseSession()
:
app.UseSession();
app.UseMvc();
現在你可以在控制器中使用它:
設置會話
string token="xx";
HttpContext.Session.SetString("UserToken", token);
獲取存儲值
var token = HttpContext.Session.GetString("UserToken");
此外,ASP.NET Core 2.1+ 引入了一些額外的擴展點,如 cookie 同意對話框。 因此,我們需要同意存儲用戶的 cookie。
如果單擊隱私橫幅上的“接受”,則 ASP.NET Core 能夠寫入會話 cookie。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.