i have two projects in my solution, UI as mvc and class project for entitiy model code first. I have severall entities in my model but now I need to extend them by new audit fields where I need to save who changed entity. I added new interface
public interface IAuditable
{
/// <summary>Gets or sets the name.</summary>
/// <value>The name.</value>
DateTime CreatedDate { get; set; }
/// <summary>Gets or sets the name.</summary>
/// <value>The name.</value>
string CreatedBy { get; set; }
/// <summary>Gets or sets the name.</summary>
/// <value>The name.</value>
DateTime UpdatedDate { get; set; }
/// <summary>Gets or sets the name.</summary>
/// <value>The name.</value>
string UpdatedBy { get; set; }
}
and try to extend SaveChanges in this way
foreach (var auditableEntity in ChangeTracker.Entries<IAuditable>())
{
if (auditableEntity.State == EntityState.Added ||
auditableEntity.State == EntityState.Modified)
{
// implementation may change based on the useage scenario, this
// sample is for forma authentication.
string currentUser = ;
// modify updated date and updated by column for
// adds of updates.
auditableEntity.Entity.UpdatedDate = DateTime.Now;
auditableEntity.Entity.UpdatedBy =
// pupulate created date and created by columns for
// newly added record.
if (auditableEntity.State == EntityState.Added)
{
auditableEntity.Entity.CreatedDate = DateTime.Now;
auditableEntity.Entity.CreatedBy = currentUser;
}
else
{
auditableEntity.Property(p => p.CreatedDate).IsModified = false;
auditableEntity.Property(p => p.CreatedBy).IsModified = false;
}
}
but how do I get the userName here ? I can't use any httpContex getUser becuase this is class project. Any ideas?
this is my contex
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IDbContext
so I thought to extend ApplicationUser by another field like LogedUserName, and fill it when user is loging, but how do I get this field in my SaveChanges method ?
If you are sure that this class library will be always used in ASP.NET pipeline you actually can access
HttpContext
. You need a reference toSystem.Web
in your class library and then:In this case
HttpContext
is a static class, not a property.Ofcourse this will fail badly if this class is ever used outside ASP.NET pipeline (for example in WPF application, console app etc). Also it doesn't seem clean to do it this way. But it's probably the fastest way which requires minimal existing code change.
Another way would be to pass either username or whole identity to either class responsible for saving changes or directly to
SaveChanges
method.One implementation could look like this:
and then in Controller (if you use context directly in MVC controllers):
where
User
is controller's property holding current user.