我有一个C#.net应用程序,我正在写一个sql server数据库。 SQL Server表都有常见的记录管理列(DateCreated,DateLastUpdated,CreatedUserId等...),我希望将这些字段的填充抽象为InsertFilter和UpdateFilter。
以下是AppHost配置方法的缩减版本。
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有任何更好的想法?
ServiceStack.dll中出现'System.NotImplementedException'类型的异常,但未在用户代码中处理
其他信息:此AppHost不支持通过Singleton访问当前请求
答案 0 :(得分:2)
User Session只能在请求的上下文中访问,因为它取决于当前请求的Session Cookies。
只有ASP.NET主机才能访问HttpContext.Current
单例来访问当前请求。尝试访问HTTP侦听器自身主机中的用户会话而不注入当前HTTP Request
时,您将收到此异常,例如:
var userSession = SessionFeature
.GetOrCreateSession<AuthUserSession>(CacheClient, Request);
我建议不要尝试访问这样的用户会话,而是在IRecordManagement
上创建一个扩展方法,填充POCO,类似于InsertFilter
正在做的事情,例如:
db.Insert(new Record { ... }.WithAudit(Request.GetSession().UserAuthId));
//Extension Method Example:
public static class RecordManagementExtensions
{
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"];
}