I have created an ADO.NET model of my database. Created a new controller with CRUD (entity framework and using the ADO.NET entity model I created).
In my database I have a simple Users table. The Password row in the table will hold the users passwords encrypted with SimpleCrypto (PBKDF2).
In my ADO.NET Users.cs model I have added following validation:
[Required]
[DataType(DataType.Password)]
[StringLength(20, MinimumLength = 6)]
[Display(Name = "Password")]
public string Password { get; set; }
That works with jQuery in the browser with validation. But in my controller I am encrypting the Password, and then the Password string will be way more than 20 chars in lenght.
var crypto = new SimpleCrypto.PBKDF2();
var encryptedPass = crypto.Compute(user.Password);
user.Password = encryptedPass;
user.PasswordSalt = crypto.Salt;
_db.Users.Add(user);
_db.SaveChanges();
And this gives me and "Validation failed for one or more entities."-error.
I can copy the user over to a "var newUser" and then set all the properties there, but isn't there a easier way to bypass the model validation in this case?
EDIT: If I remove the validation of the Password prop in the model then everything works. So it is the validation that gives me the error because I alter the Password from 6-20 length chars to +100 lengt chars because of the encryption in the controller.
EDIT: Complete controller section inserted to this question.
[HttpPost]
public ActionResult Create(Users user)
{
if (!ModelState.IsValid)
{
return View();
}
if (_db.Users.FirstOrDefault(u => u.Email == user.Email) != null)
{
ModelState.AddModelError("", "User already exists in database!");
return View();
}
var crypto = new SimpleCrypto.PBKDF2();
var encryptedPass = crypto.Compute(user.Password);
user.Password = encryptedPass;
user.PasswordSalt = crypto.Salt;
_db.Users.Add(user);
_db.SaveChanges();
return RedirectToAction("Index", "User");
}
This is where ViewModels enter the game. You should create a model which you pass to the view and map that back to the domain model later.
The ViewModel:
public class RegisterModel
{
[Required]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(20, MinimumLength = 6)]
[Display(Name = "Password")]
public string Password { get; set; }
}
The domain model (your current User
model):
public class User
{
// other properties..
[Required]
public string Password { get; set; }
}
You can use these models in your controller like this:
The GET
action:
public ActionResult Register()
{
var registerModel = new RegisterModel();
return View(registerModel)
}
With a view like this:
@model RegisterModel
@Html.LabelFor(model => model.UserName)
@Html.TextBoxFor(model => model.UserName)
@Html.ValidationMessageFor(model => model.UserName)
@Html.LabelFor(model => model.Password)
@Html.PasswordFor(model => model.Password)
@Html.ValidationMessageFor(model => model.Password)
And the POST
action:
[HttpPost]
public ActionResult Register(RegisterModel registerModel)
{
// Map RegisterModel to a User model.
var user = new User
{
UserName = registerModel.UserName,
Password = registerModel.Password // Do the hasing here for example.
};
db.Users.Add(user);
db.SaveChanges();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With