ServiceStack:访问 InsertFilter 和 UpdateFilter 中的会话
ServiceStack: Accessing the session in InsertFilter and UpdateFilter
我有一个 C#.net 应用程序,我在其中写入 sql 服务器数据库。 SQL 服务器表都有公共记录管理列(DateCreated、DateLastUpdated、CreatedUserId 等...),我希望将这些字段的填充抽象为 InsertFilter 和 UpdateFilter。
这是 AppHost 的 Configure 方法的简化版本..
public override void Configure(Container container)
{
ICacheClient CacheClient = new MemoryCacheClient();
container.Register(CacheClient);
var connectionString = ConfigurationManager.ConnectionStrings["mydb"].ConnectionString;
container.Register<IDbConnectionFactory>(c => new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider));
container.Register<IUserAuthRepository>(c => new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>()));
var authRepo = (OrmLiteAuthRepository)container.Resolve<IUserAuthRepository>();
OrmLiteConfig.InsertFilter = (dbCmd, row) =>
{
var userSession = SessionFeature.GetOrCreateSession<AuthUserSession>(CacheClient);
var recordManagementRow = row as IRecordManagement;
if (recordManagementRow != null)
{
recordManagementRow.DateCreated = recordManagementRow.DateLastUpdated = DateTime.UtcNow;
if (userSession != null)
recordManagementRow.CreatedUserId = recordManagementRow.LastUpdatedUserId = userSession.Id.ToInt();
}
};
}
执行时,我在 OrmLiteConfig.InsertFilter 委托的第一行收到以下异常。有没有人对我如何检索当前用户会话 ID 以插入数据库有更好的想法?
An exception of type 'System.NotImplementedException' occurred in ServiceStack.dll but was not handled in user code
Additional information: This AppHost does not support accessing the current Request via a Singleton
当前请求的User Session can only be accessed within the context of a request since it's dependent on the Session Cookies。
只有 ASP.NET 主机有权访问 HttpContext.Current
单例来访问当前请求。在不注入当前 HTTP Request
的情况下尝试访问 HTTP Listener Self Hosts 中的用户会话时,您将遇到此异常,例如:
var userSession = SessionFeature
.GetOrCreateSession<AuthUserSession>(CacheClient, Request);
我建议不要像这样尝试访问用户会话,而是在 IRecordManagement
上创建一个扩展方法来填充 POCO,类似于您的 InsertFilter
正在做的事情,例如:
db.Insert(new Record { ... }.WithAudit(Request));
//Extension Method Example:
public static class RecordManagementExtensions
{
public static T WithAudit<T>(this T row, IRequest req) where T : IRecordManagement =>
row.WithAudit(Request.GetSession().UserAuthId);
public static T WithAudit<T>(this T row, string userId) where T : IRecordManagement
{
row.UserId = userId;
row.DateCreated = DateTime.UtcNow;
return row;
}
}
虽然我不建议依赖 RequestContext 单例,但您可以在这种情况下使用它来为请求过滤器中的请求设置当前 UserId,例如:
GlobalRequestFilters.Add((req, res, requestDto) => {
RequestContext.Instance.Items["userId"] = req.GetSession().UserAuthId;
});
您随后可以从您的过滤器访问哪些内容,例如:
OrmLiteConfig.InsertFilter = (dbCmd, row) => {
...
recordMgt.CreatedUserId = RequestContext.Instance.Items["userId"];
}
我有一个 C#.net 应用程序,我在其中写入 sql 服务器数据库。 SQL 服务器表都有公共记录管理列(DateCreated、DateLastUpdated、CreatedUserId 等...),我希望将这些字段的填充抽象为 InsertFilter 和 UpdateFilter。
这是 AppHost 的 Configure 方法的简化版本..
public override void Configure(Container container)
{
ICacheClient CacheClient = new MemoryCacheClient();
container.Register(CacheClient);
var connectionString = ConfigurationManager.ConnectionStrings["mydb"].ConnectionString;
container.Register<IDbConnectionFactory>(c => new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider));
container.Register<IUserAuthRepository>(c => new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>()));
var authRepo = (OrmLiteAuthRepository)container.Resolve<IUserAuthRepository>();
OrmLiteConfig.InsertFilter = (dbCmd, row) =>
{
var userSession = SessionFeature.GetOrCreateSession<AuthUserSession>(CacheClient);
var recordManagementRow = row as IRecordManagement;
if (recordManagementRow != null)
{
recordManagementRow.DateCreated = recordManagementRow.DateLastUpdated = DateTime.UtcNow;
if (userSession != null)
recordManagementRow.CreatedUserId = recordManagementRow.LastUpdatedUserId = userSession.Id.ToInt();
}
};
}
执行时,我在 OrmLiteConfig.InsertFilter 委托的第一行收到以下异常。有没有人对我如何检索当前用户会话 ID 以插入数据库有更好的想法?
An exception of type 'System.NotImplementedException' occurred in ServiceStack.dll but was not handled in user code
Additional information: This AppHost does not support accessing the current Request via a Singleton
当前请求的User Session can only be accessed within the context of a request since it's dependent on the Session Cookies。
只有 ASP.NET 主机有权访问 HttpContext.Current
单例来访问当前请求。在不注入当前 HTTP Request
的情况下尝试访问 HTTP Listener Self Hosts 中的用户会话时,您将遇到此异常,例如:
var userSession = SessionFeature
.GetOrCreateSession<AuthUserSession>(CacheClient, Request);
我建议不要像这样尝试访问用户会话,而是在 IRecordManagement
上创建一个扩展方法来填充 POCO,类似于您的 InsertFilter
正在做的事情,例如:
db.Insert(new Record { ... }.WithAudit(Request));
//Extension Method Example:
public static class RecordManagementExtensions
{
public static T WithAudit<T>(this T row, IRequest req) where T : IRecordManagement =>
row.WithAudit(Request.GetSession().UserAuthId);
public static T WithAudit<T>(this T row, string userId) where T : IRecordManagement
{
row.UserId = userId;
row.DateCreated = DateTime.UtcNow;
return row;
}
}
虽然我不建议依赖 RequestContext 单例,但您可以在这种情况下使用它来为请求过滤器中的请求设置当前 UserId,例如:
GlobalRequestFilters.Add((req, res, requestDto) => {
RequestContext.Instance.Items["userId"] = req.GetSession().UserAuthId;
});
您随后可以从您的过滤器访问哪些内容,例如:
OrmLiteConfig.InsertFilter = (dbCmd, row) => {
...
recordMgt.CreatedUserId = RequestContext.Instance.Items["userId"];
}