.NET Core 3.1 复杂会话包装器不工作
.NET Core 3.1 Complex Session Wrapper Not Working
我正在尝试在 .NET Core 3.1 中创建一个复杂的会话包装器。我 运行 遇到一个问题,我的变量没有被设置。这是我设置会话包装器的方式 class.
public class SessionWrapper : ISessionWrapper
{
private static IHttpContextAccessor context;
public SessionWrapper(IHttpContextAccessor _context)
{
context = _context;
}
public static Course Course
{
get
{
var key = context.HttpContext.Session.GetString("course");
if (key == null)
{
return default;
}
else
{
return JsonConvert.DeserializeObject<Course>(key);
}
}
set
{
if(value != null)
{
context.HttpContext.Session.SetString("course", JsonConvert.SerializeObject(value));
}
}
}
}
我将我的服务配置为使用会话和会话包装器。
services.AddDistributedMemoryCache();
services.AddSession();
services.AddHttpContextAccessor();
services.AddScoped<ISessionWrapper, SessionWrapper>();
我将管道配置为使用会话
app.UseSession();
在我的控制器中,我正在初始化课程并设置会话包装器。然后,我将课程 ID 设置为 4。这不是在抱怨,而是没有设置课程 ID。它始终为空。我一直在看它,并且感到沮丧。我在这里错过了什么?
Course myCourse = new Course();
SessionWrapper.Course = myCourse;
SessionWrapper.Course.Id = "4"
我觉得您的包装器本身并不是执行此操作的最佳方法。具有 'know how' 将自身存储在 Session 中的 Course 的自我意识子类,对我来说似乎更合乎逻辑。这样您就可以将控制器从管理持久性的责任中解放出来。
public abstract class Course
{
public abstract int Id { get; set; }
}
public class SessionCourse : Course
{
private int _id;
public override int Id
{
get => _id;
set { _id = value; UpdateSession(); }
}
// The GetCourse method is a factory for creating the SessionCourse objects
// and providing it with a ISession object so they can store themselves.
public static Course GetCourse(IServiceProvider services)
{
ISession session = services.GetRequiredService<IHttpContextAccessor>()?.HttpContext.Session;
SessionCourse course = session?.GetJson<SessionCourse>("Course") ?? new SessionCourse();
course.Session = session;
return course;
}
[JsonIgnore]
private ISession Session { get; set; }
private void UpdateSession() {
Session.SetJson("Course", this);
}
}
现在的诀窍是使用将自身存储在会话中的 SessionCourse 对象来满足对 Course 对象的请求。您可以通过为课程对象添加一个带有 lambda 表达式的作用域服务来做到这一点。结果是对课程服务的请求将 return SessionCourse 对象。
services.AddScoped<Course>(sp => SessionCourse.GetCourse(sp));
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
所以创建这种服务的好处是它允许您简化使用课程对象的控制器。
public class CourseController : Controller
{
private Course course;
public CartController(Course courseService)
{
course = courseService;
}
public void SetCourseId()
{
course.Id = "4";
}
SessionExtension.cs 定义用于将对象添加到会话的扩展方法。
public static class SessionExtensions {
public static void SetJson(this ISession session, string key, object value) {
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T GetJson<T>(this ISession session, string key) {
var sessionData = session.GetString(key);
return sessionData == null ? default(T) : JsonConvert.DeserializeObject<T>(sessionData);
}
}
我正在尝试在 .NET Core 3.1 中创建一个复杂的会话包装器。我 运行 遇到一个问题,我的变量没有被设置。这是我设置会话包装器的方式 class.
public class SessionWrapper : ISessionWrapper
{
private static IHttpContextAccessor context;
public SessionWrapper(IHttpContextAccessor _context)
{
context = _context;
}
public static Course Course
{
get
{
var key = context.HttpContext.Session.GetString("course");
if (key == null)
{
return default;
}
else
{
return JsonConvert.DeserializeObject<Course>(key);
}
}
set
{
if(value != null)
{
context.HttpContext.Session.SetString("course", JsonConvert.SerializeObject(value));
}
}
}
}
我将我的服务配置为使用会话和会话包装器。
services.AddDistributedMemoryCache();
services.AddSession();
services.AddHttpContextAccessor();
services.AddScoped<ISessionWrapper, SessionWrapper>();
我将管道配置为使用会话
app.UseSession();
在我的控制器中,我正在初始化课程并设置会话包装器。然后,我将课程 ID 设置为 4。这不是在抱怨,而是没有设置课程 ID。它始终为空。我一直在看它,并且感到沮丧。我在这里错过了什么?
Course myCourse = new Course();
SessionWrapper.Course = myCourse;
SessionWrapper.Course.Id = "4"
我觉得您的包装器本身并不是执行此操作的最佳方法。具有 'know how' 将自身存储在 Session 中的 Course 的自我意识子类,对我来说似乎更合乎逻辑。这样您就可以将控制器从管理持久性的责任中解放出来。
public abstract class Course
{
public abstract int Id { get; set; }
}
public class SessionCourse : Course
{
private int _id;
public override int Id
{
get => _id;
set { _id = value; UpdateSession(); }
}
// The GetCourse method is a factory for creating the SessionCourse objects
// and providing it with a ISession object so they can store themselves.
public static Course GetCourse(IServiceProvider services)
{
ISession session = services.GetRequiredService<IHttpContextAccessor>()?.HttpContext.Session;
SessionCourse course = session?.GetJson<SessionCourse>("Course") ?? new SessionCourse();
course.Session = session;
return course;
}
[JsonIgnore]
private ISession Session { get; set; }
private void UpdateSession() {
Session.SetJson("Course", this);
}
}
现在的诀窍是使用将自身存储在会话中的 SessionCourse 对象来满足对 Course 对象的请求。您可以通过为课程对象添加一个带有 lambda 表达式的作用域服务来做到这一点。结果是对课程服务的请求将 return SessionCourse 对象。
services.AddScoped<Course>(sp => SessionCourse.GetCourse(sp));
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
所以创建这种服务的好处是它允许您简化使用课程对象的控制器。
public class CourseController : Controller
{
private Course course;
public CartController(Course courseService)
{
course = courseService;
}
public void SetCourseId()
{
course.Id = "4";
}
SessionExtension.cs 定义用于将对象添加到会话的扩展方法。
public static class SessionExtensions {
public static void SetJson(this ISession session, string key, object value) {
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T GetJson<T>(this ISession session, string key) {
var sessionData = session.GetString(key);
return sessionData == null ? default(T) : JsonConvert.DeserializeObject<T>(sessionData);
}
}