Update Using Entity Framework is not reflecting my DB table - asp.net

I'm new to Entity Framework, and wrote a function to update a particular column TStatus.
Here is what I'm trying to execute:
public ActionResult UpdateTStatus(int ICCID)
{
using (var db = new MyDBContext())
{
var result = db.INTERVIEW_AGENT_CALL_CENTERS.Where(g => g.Id == ICCID).FirstOrDefault();
if (result != null)
{
result.TStatus= 10;
db.Entry(result).State = EntityState.Modified;
db.SaveChanges();
return Content("Result = "+result.TStatus);
}
else
{
return Content("An Error");
}
}
return View();
}
Whenever I'm executing the method and run a direct query on SQL Server, I'm getting the old value of TStatus.

Related

Cannot post update to database. not all code paths return a value

[HttpPost]
public ActionResult UpdateDetail(User user)
{
bool Status = false;
string message = "";
// Model Validation
if (ModelState.IsValid)
{
using (UsersDatabaseEntities ude = new UsersDatabaseEntities())
{
var v = ude.Users.Where(a => a.Email == User.Identity.Name).FirstOrDefault();
user = v;
ude.Entry(User).State = EntityState.Modified;
ude.SaveChanges();
}
return View(user);
}
}
I keep on getting an error while saving data to the database.
UpdateDetail worked while retrieving message, but i keep getting error when saving.
Your issue is if your ModelState.IsValid == false, then you are not returning anything. I put a comment in code below where it is.
Depending on what your logic needs to do, would determine what needs to be returned if IsValid == false
public ActionResult UpdateDetail(User user)
{
bool Status = false;
string message = "";
// Model Validation
if (ModelState.IsValid)
{
using (UsersDatabaseEntities ude = new UsersDatabaseEntities())
{
var v = ude.Users.Where(a => a.Email == User.Identity.Name).FirstOrDefault();
user = v;
ude.Entry(User).State = EntityState.Modified;
ude.SaveChanges();
}
// this is your issue, this needs to be outisde the if statement, or you have to do an else and return null (or whatever you need to based off your logic)
return View(user);
}
}
Keep return statement outside of If statement. this would fix your error.If model is valid model updated with user details from database will be pushed to View. other wise same user model will be pushed to the view.
[HttpPost]
public ActionResult UpdateDetail(User user)
{
bool Status = false;
string message = "";
// Model Validation
if (ModelState.IsValid)
{
using (UsersDatabaseEntities ude = new UsersDatabaseEntities())
{
var v = ude.Users.Where(a => a.Email == User.Identity.Name).FirstOrDefault();
user = v;
ude.Entry(User).State = EntityState.Modified;
ude.SaveChanges();
}
}
return View(user);
}

Invalid object name 'AspNetRoleClaims' exception when logging in

So I implemented Identity for my core project. I have successfully completed my Registration. So while trying to login using the _signInManager.PasswordSignInAsync I am getting the exception Invalid object name 'AspNetRoleClaims'.
I know this is because the AspNetRoleClaims table is not present in my database. But idont know the structure of this table nor do I know how to create it automatically like in mvc.
Can somebody enlighten me why this table is used. Or at least what is the expected structure.
public async Task<IActionResult> RegisterSubmit(Registermodel rm)
{
if (rm.role == "" || rm.role.Trim() == "-1")
{
return View();
}
else
{
var user = new ApplicationUser { UserName = rm.username, Email = rm.username, DeptName = rm.role };
var result = await _userManager.CreateAsync(user, rm.Password);
if (result.Succeeded)
{
_userManager.GenerateEmailConfirmationTokenAsync(user);
await _signInManager.SignInAsync(user, isPersistent: false);
var roleexists = await _roleManager.RoleExistsAsync(rm.role);
if (!roleexists)
{
var role = new IdentityRole();
role.Name = rm.role;
await _roleManager.CreateAsync(role);
}
await _userManager.AddToRoleAsync(user, rm.role);
user.Claims.Add(new IdentityUserClaim<string>
{
ClaimType = "ProductUploadRequest",
ClaimValue = "Allow"
});
}
return View("Login");
}
}
This is my login method.
public async Task<IActionResult> Login(LoginIdentityModel lim)
{
var result = await _signInManager.PasswordSignInAsync(lim.username, lim.password,false, lockoutOnFailure: false); //exception comes here
if (result.Succeeded)
{
var user = await _userManager.GetUserAsync(HttpContext.User);
UserProfileInfo userProfileInfo = new UserProfileInfo();
userProfileInfo.UserId = new Guid(user.Id);
userProfileInfo.FirstName = "test";
userProfileInfo.UserName = lim.username;
userProfileInfo.LastVisit = DateTime.Now;
string query2 = "select ud.UserId,dp.Id DeptId,dp.Name DeptName,rd.Id RoleId,rd.Name RoleName,ud.[ReadWrite] from UserInDepartment ud inner join Department dp on ud.DeptId=dp.Id inner join RolesInDepartment rd on dp.Id=rd.DeptId and ud.RoleId=rd.Id where ud.UserId='" + user.Id + "' and dp.IsEnable=1 and rd.IsEnable=1 and ud.IsEnable=1";
var userProfile = await _departMentalContext.UserProfiles.FromSql(query2).SingleOrDefaultAsync();
if (userProfile != null)
{
Dictionary<int, string> deptValues = new Dictionary<int, string>() { { userProfile.DeptId, userProfile.DeptName } };
userProfileInfo.Dept = deptValues;
Dictionary<int, string> roleValues = new Dictionary<int, string>() { { userProfile.RoleId, userProfile.RoleName } };
userProfileInfo.Role = roleValues;
userProfileInfo.ReadOrWrite = userProfile.ReadWrite;
HttpContext.Session.SetObject(UserProfileSessionName, userProfileInfo);
}
return View("/Home/DashBoard");
}
return View();
}
As you are using EF, you should be able to update your model database.
You can use CLI command (learn.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet).
Or if you are using Visual Studio, in the package manager console, you can execute those commands :
Add-Migration "init"
Update-Database
Commands allows you tu update table in your database. Also, it will create migrations files, which are a "picture" of your models. When the command Update-Database is executed, it loads the last migration file.

Remove roleClaims at one Query shot asp.net Core

I am using asp.net core RoleManager to perform roleClaim(permission) based authorization. The below code work fine but it take too much time execute because i delete the roleclaim each at a time. but i want to delete roleclaims(permission) at one shot delete query , Can anyone help me ? thank's in advance.
//my controller code
public async Task<IActionResult> SaveRolePermission([FromBody] RoleClaimVM model)
{
try
{
if (string.IsNullOrEmpty(model.RoleId) || model.ClaimValues.Length <= 0) return Json(new { status = false });
var role = await _roleManager.FindByIdAsync(model.RoleId);
if (role == null) return null;
var roleClaims = _roleManager.GetClaimsAsync(role).Result.ToList();
if (roleClaims.Any())
{
foreach (var item in roleClaims)
{
await _roleManager.RemoveClaimAsync(role, item);
}
}
foreach (var item in model.ClaimValues)
{
await _roleManager.AddClaimAsync(role, new Claim(CustomClaimtypes.Permission, item.ToLower()));
}
return Json(new { status = true });
}
catch (Exception)
{
return Json(new { status = false });
}
}

The procedure does not work properly Entity Framework ASP.NET MVC 5 C#5

I have been facing this problem with assigning users to a proper role. The code looks just fine, but in reality half of the users gets a proper role, the other half stays without a role at all. Here is the method which does it:
public IdentityResult RefreshUserGroupRoles(long? userId)
{
if (userId == null) throw new ArgumentNullException(nameof(userId));
var user = _userManager.FindById(userId.Value);
if(user == null)
{
throw new ArgumentNullException(nameof(userId));
}
// Remove user from previous roles:
var oldUserRoles = _userManager.GetRoles(userId.Value);
if (oldUserRoles.Count > 0)
{
_userManager.RemoveFromRoles(userId.Value, oldUserRoles.ToArray());
}
// Find the roles this user is entitled to from group membership:
var newGroupRoles = this.GetUserGroupRoles(userId.Value);
// Get the damn role names:
var allRoles = _roleManager.Roles.ToList();
var addTheseRoles = allRoles.Where(r => newGroupRoles.Any(gr => gr.AppRoleId == r.Id));
var roleNames = addTheseRoles.Select(n => n.Name).ToArray();
//_db.Database.CurrentTransaction.Commit();
// Add the user to the proper roles
var transaction = _db.Database.BeginTransaction();
IdentityResult result;
try
{
result = _userManager.AddToRoles(userId.Value, roleNames);
transaction.Commit();
_db.DbContextTransactionAu.Commit(); //This is for Audit
}
catch (Exception)
{
transaction.Rollback();
throw;
}
_db.DbContextTransactionAuDispose?.Dispose();
return result;
}
public IEnumerable<AppGroupRole> GetUserGroupRoles(long userId)
{
var userGroups = this.GetUserGroups(userId).ToList();
if (userGroups.Count == 0) return new Collection<AppGroupRole>().AsEnumerable();
var userGroupRoles = new List<AppGroupRole>();
foreach(var group in userGroups)
{
userGroupRoles.AddRange(group.AppRoles.ToArray());
}
return userGroupRoles;
}
Any idea what could be wrong?

release_mode, Pooling, Max Pool size for InMemory SQLite with FluentNHibernate

I'm having some trouble with Sqlite in memory.
I have a class that has a CPF field - similar to US' SSN. As a bussiness rule, the CPF must be unique in the system.
So I've decided to make a check on the class that has this field. Now maybe there's code smell here: I check with the ORM if this is a Conflicting CPF.
private CPF cpf;
public virtual CPF CPF
{
get { return cpf; }
set
{
if (this.ormCreated) //Do not check if it is loaded from the DB. Otherwise, it loops, generating a StackOverflow exception
{
cpf = value;
}
else
{
this.setNewCpf(value);
}
}
}
private void setNewCpf(CPF newCpf)
{
if (this.cpf == newCpf)
{
return;
}
if (Helper.Orm.IsConflictingCpf(newCpf))
{
throw new ConflictingCpfException();
}
else
{
cpf = newCpf;
}
}
And here is the implementation, on the ORM Helper class.
bool OrmHelper.IsConflictingCpf(CPF cpf)
{
int? cpfNumber = cpf.NumeroSemDV;
if (cpfNumber.HasValue)
{
var teste = findByCpfNumber<Client>(cpf);
return
(
findByCpfNumber<Client>(cpf) != null ||
findByCpfNumber<Adversary>(cpf) != null
);
}
else
{
//CPFSemDV = Nullable
return false;
}
}
private PersonType findByCpfNumber<PersonType> (CPF cpf) where PersonType : PessoaFisica
{
int? cpfNumber = cpf.NumeroSemDV;
using (var session = this.NewSession())
using (var transaction = session.BeginTransaction())
{
try
{
var person = session.Query<PersonType>()
.Where(c => c.CPF.NumeroSemDV == cpfNumber)
.FirstOrDefault<PersonType>();
return person;
}
catch (Exception) { transaction.Rollback(); }
finally
{
session.Close();
}
}
return null;
}
The problem happens in my tests. I'm using FluentNHibernate and In memory SQLite.
protected override FluentConfiguration PersistenceProvider
{
get
{
return Fluently
.Configure()
.Database(
SQLiteConfiguration
.Standard
.InMemory()
.ShowSql()
);
}
}
Here is the failing test.
protected override void Given()
{
base.Given();
var clients = new List<Client>();
Client client1 = new Client("Luiz Angelo Heinzen")
{
Capaz = true,
CPF = new CPF(18743509),
eMail = "lah#furb.br"
};
session.Save(client1);
session.Evict(client1);
}
[Then]
public void Motherfaker()
{
Client fromDb;
var clientsFromDb = session.Query<Client>()
.Where(c => c.eMail == "lah#furb.br");
fromDb = clientsFromDb.FirstOrDefault<Client>();
Assert.AreEqual(fromDb.FullName, "Luiz Angelo Heinzen");
}
The reason it fails? In the beginning it was failing because the table didn't exist. In memory sqlite destroys the schema on each new session. So I changed the code to return the same session on the NewSession(). But now it fails with a NHibernate exception: Session is closed. I've tested and if change the findByCpfNumber from this
private PersonType findByCpfNumber<PersonType> (CPF cpf) where PersonType : PessoaFisica
{
int? cpfNumber = cpf.NumeroSemDV;
using (var session = this.NewSession())
using (var transaction = session.BeginTransaction())
{
try
{
var person = session.Query<PersonType>()
.Where(c => c.CPF.NumeroSemDV == cpfNumber)
.FirstOrDefault<PersonType>();
return person;
}
catch (Exception) { transaction.Rollback(); }
finally
{
session.Close();
}
}
return null;
}
to this
private PersonType findByCpfNumber<PersonType> (CPF cpf) where PersonType : PessoaFisica
{
int? cpfNumber = cpf.NumeroSemDV;
//using (var session = this.NewSession())
var session = this.NewSession();
using (var transaction = session.BeginTransaction())
{
try
{
var person = session.Query<PersonType>()
.Where(c => c.CPF.NumeroSemDV == cpfNumber)
.FirstOrDefault<PersonType>();
return person;
}
catch (Exception) { transaction.Rollback(); }
finally
{
//session.Close();
this.CloseSession(session);
}
}
this.CloseSession(session);
return null;
}
the error doesn't happen anymore. Obviously, I'd have to implement the CloseSession method. It would close the Session on the Production database and it would do nothing if Sqlite is being used.
But I'd rather configure SQLite in someway that it wouldn't dispose the session. I've read here about release_mode, Pooling and Max Pool atributes. But I can't seem to find it in the FluentNHibernate so can't even test to see if it would work. I have the FluentNHibernate cloned and it seems to set the release_mode set to on_close, but that doesn't help.
I've even tried:
public override ISession NewSession()
{
if (this.session == null)
{
if (sessionFactory == null)
{
CreateSessionFactory();
}
this.session = sessionFactory.OpenSession();
}
if (!session.IsOpen)
{
sessionFactory.OpenSession(session.Connection);
session.Connection.Open();
}
return session;
}
But it keeps telling me that the Session is closed. So, anyone has any suggestions on how to approach this?
Or does this so smelly that's beyond salvation?
I hope this is clear enough. And forgive my mistakes: I'm from Brazil and not a native english speaker.
Thanks,
Luiz Angelo.
i would check for uniqueness when creating CPFs in the system and have an additional Unique constraint in the database to enforce that. Then if you set cascading to none for each reference to CPF (default is none) it is not possible to assigne newly created duplicate CPFs to an Entity and save it without exception, so it can't happen accidently.
I had the same problem. What's happening is that in-memory SQLite will drop the entire schema when the connection is closed. If you create a session that you hold on to for all tests, it will retain the structure for all other sessions.
For code and a fuller explanation, check out this answer: Random error when testing with NHibernate on an in-Memory SQLite db

Resources