将数据从 ASP .NET MVC 应用程序传递到 NHibernate 事件侦听器
passing data from ASP .NET MVC application into NHibernate Event listener
我已经向 orm 添加了一些审计(IPostUpdateEventListener、IPostInsertEventListener、IPostDeleteEventListener)。很好用。
问题是我想记录用户名和 ip 地址,从那里完成了对数据库的请求以及其他一些额外信息。
我有 3 个模块:Web、ORM 和 Shared。网络 -> 共享 <- ORM。
Web 通过位于 Shared 上的接口访问 ORM。我怎样才能在请求中添加更多信息? (或者准确地说是 nhibernate 会话)所以我可以从事件监听器代码中调用它。
谢谢:)
找到了解决办法。
事件侦听器如下所示:
public class AuditUpdateListener : IPostUpdateEventListener
{
public void OnPostUpdate(PostUpdateEvent @event)
{
// logging code
}
}
我发现这个 "magic" 对象叫做 CallContext.HostContext https://msdn.microsoft.com/en-us/library/system.runtime.remoting.messaging.callcontext.hostcontext(v=vs.110).aspx
到目前为止没有什么特别的,但是你将它转换为 HttpContext 并且你可以获得所有需要的信息
public class AuditUpdateListener : IPostUpdateEventListener
{
public void OnPostUpdate(PostUpdateEvent @event)
{
var httpContext = CallContext.HostContext as HttpContext;
var ipAddress = httpContext.Request.UserHostAddress;
var username = httpContext.User.Identity.Name;
// some code to get values from httpContext.Request.Cookies
}
}
这是我的一位听众的例子。它与 NHibernate Cookbook 中的布局几乎相同。请注意,我只有一个方法可以从 HttpContext 或 WindowsIdentity 中获取用户名。如果您知道您总是要通过网络拨打电话,那么您应该始终定义 HttpContext.Current。只需从那里获取任何想要的信息。它应该允许您访问他的请求。
public class EventListener : IPreInsertEventListener, IPreUpdateEventListener
{
private readonly IStamper _stamper;
public EventListener() : this(new Stamper()) { }
public EventListener(IStamper stamper)
{
_stamper = stamper;
}
#region IPreInsertEventListener Members
public bool OnPreInsert(PreInsertEvent @event)
{
_stamper.Insert(@event.Entity as IStampedEntity, @event.State, @event.Persister);
return false;
}
#endregion
#region IPreUpdateEventListener Members
public bool OnPreUpdate(PreUpdateEvent @event)
{
_stamper.Update(@event.Entity as IStampedEntity, @event.OldState, @event.State, @event.Persister);
return false;
}
#endregion
}
public interface IStamper
{
void Insert(IStampedEntity entity, object[] state, IEntityPersister persister);
void Update(IStampedEntity entity, object[] oldState, object[] state, IEntityPersister persister);
}
public class Stamper : IStamper
{
private const String CreateUser = "CreateUser";
private const String CreateDate = "CreateDate";
private const String LastUpdateUser = "LastUpdateUser";
private const String LastUpdateDate = "LastUpdateDate";
public void Insert(IStampedEntity entity, object[] state, IEntityPersister persister)
{
if (entity == null)
return;
SetCreate(entity, state, persister);
SetChange(entity, state, persister);
}
public void Update(IStampedEntity entity, object[] oldState, object[] state, IEntityPersister persister)
{
if (entity == null)
return;
SetChange(entity, state, persister);
}
private void SetCreate(IStampedEntity entity, object[] state, IEntityPersister persister)
{
entity.CreateUser = GetUserName();
SetState(persister, state, CreateUser, entity.CreateUser);
entity.CreateDate = DateTime.UtcNow;
SetState(persister, state, CreateDate, entity.CreateDate);
}
private void SetChange(IStampedEntity entity, object[] state, IEntityPersister persister)
{
entity.LastUpdateUser = GetUserName();
SetState(persister, state, LastUpdateUser, entity.LastUpdateUser);
entity.LastUpdateDate = DateTime.UtcNow;
SetState(persister, state, LastUpdateDate, entity.LastUpdateDate);
}
private void SetState(IEntityPersister persister, IList<object> state, String propertyName, object value)
{
var index = GetIndex(persister, propertyName);
if (index == -1)
return;
state[index] = value;
}
private Int32 GetIndex(IEntityPersister persister, String propertyName)
{
return Array.IndexOf(persister.PropertyNames, propertyName);
}
private String GetUserName()
{
if (HttpContext.Current != null)
return HttpContext.Current.User.Identity.Name;
var windowsIdentity = WindowsIdentity.GetCurrent();
return windowsIdentity != null ? windowsIdentity.Name : String.Empty;
}
}
我已经向 orm 添加了一些审计(IPostUpdateEventListener、IPostInsertEventListener、IPostDeleteEventListener)。很好用。 问题是我想记录用户名和 ip 地址,从那里完成了对数据库的请求以及其他一些额外信息。
我有 3 个模块:Web、ORM 和 Shared。网络 -> 共享 <- ORM。 Web 通过位于 Shared 上的接口访问 ORM。我怎样才能在请求中添加更多信息? (或者准确地说是 nhibernate 会话)所以我可以从事件监听器代码中调用它。
谢谢:)
找到了解决办法。 事件侦听器如下所示:
public class AuditUpdateListener : IPostUpdateEventListener
{
public void OnPostUpdate(PostUpdateEvent @event)
{
// logging code
}
}
我发现这个 "magic" 对象叫做 CallContext.HostContext https://msdn.microsoft.com/en-us/library/system.runtime.remoting.messaging.callcontext.hostcontext(v=vs.110).aspx
到目前为止没有什么特别的,但是你将它转换为 HttpContext 并且你可以获得所有需要的信息
public class AuditUpdateListener : IPostUpdateEventListener
{
public void OnPostUpdate(PostUpdateEvent @event)
{
var httpContext = CallContext.HostContext as HttpContext;
var ipAddress = httpContext.Request.UserHostAddress;
var username = httpContext.User.Identity.Name;
// some code to get values from httpContext.Request.Cookies
}
}
这是我的一位听众的例子。它与 NHibernate Cookbook 中的布局几乎相同。请注意,我只有一个方法可以从 HttpContext 或 WindowsIdentity 中获取用户名。如果您知道您总是要通过网络拨打电话,那么您应该始终定义 HttpContext.Current。只需从那里获取任何想要的信息。它应该允许您访问他的请求。
public class EventListener : IPreInsertEventListener, IPreUpdateEventListener
{
private readonly IStamper _stamper;
public EventListener() : this(new Stamper()) { }
public EventListener(IStamper stamper)
{
_stamper = stamper;
}
#region IPreInsertEventListener Members
public bool OnPreInsert(PreInsertEvent @event)
{
_stamper.Insert(@event.Entity as IStampedEntity, @event.State, @event.Persister);
return false;
}
#endregion
#region IPreUpdateEventListener Members
public bool OnPreUpdate(PreUpdateEvent @event)
{
_stamper.Update(@event.Entity as IStampedEntity, @event.OldState, @event.State, @event.Persister);
return false;
}
#endregion
}
public interface IStamper
{
void Insert(IStampedEntity entity, object[] state, IEntityPersister persister);
void Update(IStampedEntity entity, object[] oldState, object[] state, IEntityPersister persister);
}
public class Stamper : IStamper
{
private const String CreateUser = "CreateUser";
private const String CreateDate = "CreateDate";
private const String LastUpdateUser = "LastUpdateUser";
private const String LastUpdateDate = "LastUpdateDate";
public void Insert(IStampedEntity entity, object[] state, IEntityPersister persister)
{
if (entity == null)
return;
SetCreate(entity, state, persister);
SetChange(entity, state, persister);
}
public void Update(IStampedEntity entity, object[] oldState, object[] state, IEntityPersister persister)
{
if (entity == null)
return;
SetChange(entity, state, persister);
}
private void SetCreate(IStampedEntity entity, object[] state, IEntityPersister persister)
{
entity.CreateUser = GetUserName();
SetState(persister, state, CreateUser, entity.CreateUser);
entity.CreateDate = DateTime.UtcNow;
SetState(persister, state, CreateDate, entity.CreateDate);
}
private void SetChange(IStampedEntity entity, object[] state, IEntityPersister persister)
{
entity.LastUpdateUser = GetUserName();
SetState(persister, state, LastUpdateUser, entity.LastUpdateUser);
entity.LastUpdateDate = DateTime.UtcNow;
SetState(persister, state, LastUpdateDate, entity.LastUpdateDate);
}
private void SetState(IEntityPersister persister, IList<object> state, String propertyName, object value)
{
var index = GetIndex(persister, propertyName);
if (index == -1)
return;
state[index] = value;
}
private Int32 GetIndex(IEntityPersister persister, String propertyName)
{
return Array.IndexOf(persister.PropertyNames, propertyName);
}
private String GetUserName()
{
if (HttpContext.Current != null)
return HttpContext.Current.User.Identity.Name;
var windowsIdentity = WindowsIdentity.GetCurrent();
return windowsIdentity != null ? windowsIdentity.Name : String.Empty;
}
}