简体   繁体   中英

passing data from ASP .NET MVC application into NHibernate Event listener

I've added some auditing to the orm (IPostUpdateEventListener, IPostInsertEventListener, IPostDeleteEventListener). works nice. The problem is that i want to log the username and the ip address from where a request to the database has been done along with some other extra information.

I have 3 modules: Web, ORM and Shared . Web -> Shared <- ORM. Web accesses ORM through interfaces that are located on Shared. How could I add some more information on the requests? (or the nhibernate session to be exact) So i can call it from the Event Listener code.

Thanks :)

Here's an example of one of my listeners. it's almost identical as layed out in NHibernate Cookbook. Notice I just have a method that grabs the username from either the HttpContext or WindowsIdentity. If you know you are always going to make your calls from the web, you should always have the HttpContext.Current defined. Just grab whatever information want from there. It should give you access to he request.

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;
    }
}

found a solution. the event listener looks like this :

public class AuditUpdateListener : IPostUpdateEventListener
{

    public void OnPostUpdate(PostUpdateEvent @event)
    {
      // logging code
    }
}

and i found this "magic" object called CallContext.HostContext https://msdn.microsoft.com/en-us/library/system.runtime.remoting.messaging.callcontext.hostcontext(v=vs.110).aspx

nothing fancy so far, but then you cast it to HttpContext and you can get all the needed information

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
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM