I want in my context partial class to add some "automated" functionalities such as CreatedBy
and ModifiedBy
.
I have 2 projects: DataAccess and MVC (StartUp project).
I cannot get an assembly reference in my context partial class in folder Context (please, see the photo), is there any way to do this? I have installed all necessary nu-get components
So, I have red underline when I try to call User.Identity.GetUserId();
As you can see on the image, I even pulled out class IdentityModels.cs in that Project (DataAccess), but with no luck.
my context class looks like:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Data.SqlClient;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.VisualBasic.ApplicationServices;
using Owin;
namespace DataAccess
{
public partial class SalesManagementEntities
{
private bool doSaveChangesOverride = true;
public bool DoSaveChangesOverride
{
set { doSaveChangesOverride = value; }
get { return doSaveChangesOverride; }
}
public override int SaveChanges()
{
try
{
if (DoSaveChangesOverride)
SaveChangesOverride();
return base.SaveChanges();
}
catch (Exception ex)
{
throw ex;
}
}
public override Task<int> SaveChangesAsync()
{
if (DoSaveChangesOverride)
SaveChangesOverride();
return base.SaveChangesAsync();
}
private void SaveChangesOverride()
{
ObjectContext context = ((IObjectContextAdapter)this).ObjectContext;
//Find all Entities that are Added/Modified that inherit from my EntityBase
IEnumerable<ObjectStateEntry> objectStateEntries =
from e in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)
where
e.IsRelationship == false &&
e.Entity is IEntityBase
select e;
var currentTime = DateTime.Now;
string userId = User.Identity.GetUserId();
foreach (var entry in objectStateEntries)
{
var entityBase = entry.Entity as IEntityBase;
if (entry.State == EntityState.Added)
{
entityBase.SetCreatedDateTime(currentTime);
entityBase.SetCreatedBy(userId);
}
entityBase.SetModifiedDateTime(currentTime);
entityBase.SetModifiedBy(userId);
}
}
}
}
The following code :
User.Identity.GetUserId();
will work only if you are inside a mvc controller because a mvc controller exposes a property named User
which is in IPrincipal
type that let you get access to IPrincipal
members like Identity
etc...
Your DbContext
doesn't have a User
property but a User
class and the compiler attempts to check if a static property named Identity
exist into a that class and will not find that property and finally raises an error for that.
To get the current user Id in your DAL layer you must use the following code :
// There is no nuget package to install to get the user name.
// If the user name is unique into your database table then
// you can request your DbContext and get the user id.
var userName = System.Web.HttpContext.Current.User.Identity.Name;
If you want to get the user id like you will do into your controller by using GetUserId
or GetUserId<T>
extension methods then use the following code :
// You need to install the Microsoft.AspNet.Identity.Core nuget package
// and get the user id like this:
var userId = System.Web.HttpContext.Current.User.Identity.GetUserId();
I recommend you to use a service that will give you the current IIdentity
. Doing that will help for unit tests because mocking the current user will be easy.