Reputation: 141
I want to register new user in my application, so I have following components: Registration model
public class RegisterModel
{
[Required]
public string Login { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "Passwords doesn't match")]
public string PasswordCompare { get; set; }
[Required]
public int Tier { get; set; }
}
Which connected to a form
<form asp-antiforgery="true" method="post" role="form">
<div class="validation" asp-validation-summary="ModelOnly"></div>
<div class="form-group">
<label for="Login">Login:</label>
<div>
<input required asp-for="Login" type="text" name="Login" value="@Model?.Login">
</div>
</div>
<div class="form-group">
<label asp-for="Password">Password</label>
<input asp-for="Password" type="password" />
<span asp-validation-for="Password" />
</div>
<div class="form-group">
<label asp-for="PasswordCompare">Confirm password</label>
<input asp-for="PasswordCompare" type="password" />
<span asp-validation-for="PasswordCompare" />
</div>
<div class="form-group">
<label for="Tier">Tier of access:</label>
<div>
<input required asp-for="Tier" type="number" name="Tier" value="@Model?.Tier">
</div>
</div>
<div class="form-group">
<input type="submit" value="Create" />
</div>
</form>
Table in my db representing user
CREATE TABLE [dbo].[AdministratorUsers] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Login] NVARCHAR (MAX) NOT NULL,
[PasswordHash] NVARCHAR (MAX) NOT NULL,
[Tier] INT NOT NULL,
CONSTRAINT [PK_AdministratorUsers] PRIMARY KEY CLUSTERED ([Id] ASC)
);
And class entity
public class AdministratorUser
{
[Key]
public int Id { get; set; }
public string Login { get; set; }
public string PasswordHash { get; set; }
public int Tier { get; set; } = 0;
}
And action which reforms registration model into user entity and saves it to db.
[HttpPost("accounts/create", Name = "AdminAccountCreate")]
public async Task<IActionResult> Create([FromServices] IGenPasswordHash genPassHash, RegisterModel regModel)
{
string passwordHash = genPassHash.GenerateHash(regModel.Password);
await db.AdministratorUsers.AddAsync(new AdministratorUser
{
Login = regModel.Login,
PasswordHash = passwordHash,
Tier = regModel.Tier
});
return RedirectToAction("Accounts");
}
But somehow it doesn't working. I already fixed all potential that I could find and this is most clear version that Im able to provide.
Upvotes: 3
Views: 79
Reputation: 2662
You need to submit the changes after you've added an entity. You do that by writing db.AdministratorUsers.SaveChanges()
for your specific case.
EDIT: It seems .AddAsync()
does no such thing (see edit revisions). I'll continue to investigate this and edit this answer if I get an insight to how exactly the async operations differ from the normal ones. In an essence - if you're adding a huge object and don't mind necessarily waiting for the object to be added, in order for the thread in question to finish the user's request, you shouldn't be using Async. But if you're not dependent on that, if you're fine with allowing a separate thread to take care of that operation for you, while the client sending the request gets an "Ok" that everything's been resolved successfully, or by doing other tasks in the meantime, go for the .Async
variant.
The reason I thought it did something amongst those lines is because I used .SaveChangesAsync()
once, and it added my object with a 5 second delay, whereas without Async it does so without any interruption. My application is heavily dependent on the objects being added to the database at the end of an issued user request, hence why I never tried it again.
Upvotes: 2
Reputation: 67
You need to call the db.SaveChanges() method, otherwise the changes won't make it to the database.
[HttpPost("accounts/create", Name = "AdminAccountCreate")]
public async Task<IActionResult> Create([FromServices] IGenPasswordHash genPassHash, RegisterModel regModel)
{
string passwordHash = genPassHash.GenerateHash(regModel.Password);
await db.AdministratorUsers.AddAsync(new AdministratorUser
{
Login = regModel.Login,
PasswordHash = passwordHash,
Tier = regModel.Tier
});
// Add this
db.SaveChanges();
return RedirectToAction("Accounts");
}
Upvotes: 1
Reputation: 98
You should call SaveChanges function after AddAsync method.
db.AdministratorUsers.SaveChanges();
Upvotes: 2