1

I have an MVC intranet application which uses EF 6. I have setup the DataAccess project in a separate class library which has EF 6 referenced. I have an entity which implements an interface:

public interface IAuditable
{
    DateTime CreatedDateTime { get; set; }
    string CreatedBy { get; set; }
}

public class Collection : IAuditable
{
    // Properties
}

However, in the SaveChanges method I obviously don't have access to HttpContext.Current.User.Identity.Name as it is in a separate class library, so I was wondering how one would set this in SaveChanges?

public override int SaveChanges()
{
    var addedEntries = ChangeTracker.Entries().Where(x => x.State == EntityState.Added);

    foreach (var dbEntityEntry in addedEntries)
    {
        var entity = dbEntityEntry.Entity as IAuditable;

        if (entity != null)
        {
            entity.CreatedDateTime = DateTime.Now;
            // how do I set entity.CreatedBy = HttpContext.Current.User.Identity.Name?
        }
    }

    return base.SaveChanges();
}

Edit

Following on from @CodeCaster solution, I have the following:

[BreezeController]
public class BreezeController : ApiController
{
    private readonly BTNIntranetRepository _repository; 

    public BreezeController(BTNIntranetRepository repository)
    {
        _repository = repository;
        _repository.LoggedInUser = HttpContext.Current.User.Identity.Name;
    }

    // Methods
}

But HttpContext.Current.User is null

tchrist
  • 78,834
  • 30
  • 123
  • 180
CallumVass
  • 11,288
  • 26
  • 84
  • 154
  • The fact your `HttpContext.Current.User` is null is an entirely different issue, that might arise from how you set up your authentication and IoC container. What's it set to in an action method? A hack would be to set it each time on a repository before using it, but in that case you might as wel do `entity.CreatedBy=...`. – CodeCaster Jan 07 '14 at 15:38
  • I've enabled Windows Auth and I can see the value of `Identity.Name` if I don't set it in the constructor (for example in one of the methods on the ApiController) but if I do, then `User` is null – CallumVass Jan 07 '14 at 15:42

1 Answers1

1

This can be solved in many ways.

You're not really showing relevant code, but you can for example give the library class you expose a public string LoggedInUser (or ActingUser or give it a name) property which you set when instantiating it:

public class SomeController : Controller
{
    private IDataSource _dataSource;

    public SomeController(IDataSource dataSource)
    {
        _dataSource = dataSource;
        _dataSource.LoggedInUser = HttpContext.Current.User.Identity.Name
    }
}

You can then simply use that property in your IDataSource.SaveChanges() method:

public override int SaveChanges()
{
    // ...

    entity.CreatedBy = this.LoggedInUser;
}
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • The controller is an ApiController. The problem with setting it in the constructor is that the HttpContext.Current.User isn't set when I instantiate the controller in my IoC – CallumVass Jan 07 '14 at 15:33
  • 1
    I've edited my question to hopefully show more relevant code? – CallumVass Jan 07 '14 at 15:38
  • 1
    What I've done, is prior to calling SaveChanges on my repo, I call a method to set the current user on my repo, this in turn sets the value of `LoggedInUser` in the context and solved the problem! Thanks! – CallumVass Jan 07 '14 at 15:53