我有一个 C#.net 应用程序,我正在其中写入 SQL Server 数据库。 SQL Server 表都有公共(public)记录管理列(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 委托(delegate)的第一行出现以下异常。对于如何检索当前用户 session 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只能在请求的上下文中访问,因为它依赖于 Session Cookies当前请求。
只有 ASP.NET 主机有权访问 HttpContext.Current
单例来访问当前请求。当尝试访问 HTTP 监听器自主机中的用户 session 而不注入(inject)当前的 HTTP Request
时,您将收到此异常,例如:
var userSession = SessionFeature
.GetOrCreateSession<AuthUserSession>(CacheClient, Request);
我建议不要尝试像这样访问用户 session ,而是在 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# - ServiceStack:访问InsertFilter和UpdateFilter中的 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35629080/