I have created a new MVC project (default MVC5 Individual User Accounts template) and I have made changes to IdenitityConfig.cs
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 1,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = false,
RequireUppercase = false,
};
But still while registration it gives an error "The Password must be at least 6 characters long."
But I have changed length to 1.
Its not passing the viewmodel validation.
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
//[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
If you remove this line [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)], you will not have this issue.
Related
I'm using Identity, and the IdentityUsers properties are the next: https://msdn.microsoft.com/en-us/library/microsoft.aspnet.identity.entityframework.identityuser_properties%28v=vs.108%29.aspx
Well, the problem is I have in the AspNetUsers table "Email" and "PasswordHash", but appears the error'System.ComponentModel.DataAnnotations.DataType' does not contain a definition for 'Email' and 'PasswordHash')
if I put "Datatype.Email" instead of "DataType.EmailAddress" and "DataType.PasswordHash" instead of "DataTtype.Password".
public class RegisterViewModel
{
[Required]
[DataType(DataType.Email)]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The password must have at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.PasswordHash)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.PasswordHash)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "Different passwords.")]
public string ConfirmPassword { get; set; }
}
The error is telling you exactly what you need. DataType is an enumeration which only allows specific values. These in turn are used for validation in the MVC world to ensure that you have a valid EmailAddress in the field, whatever it happens to be called.
[DataType(DataType.Email)] // Not Valid
[DataType(DataType.EmailAddress)] // Valid
[DataType(DataType.PasswordHash)] // Not Valid
[DataType(DataType.Password)] // Valid
For the full list of valid values, see Intellisense or this URL:
https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.datatype%28v=vs.110%29.aspx
I am using Identity in my MVC project, and it's all well and nice. Except the fact that the form for registering a new user has some crazy password requirements
Passwords must have at least one non letter or digit character. Passwords must have at least one digit ('0'-'9'). Passwords must have at least one uppercase ('A'-'Z').
And here is the register model
public class RegisterViewModel
{
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 2)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Passord")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Repeat Password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
Account Controller
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
I see the length requirement for the password, but I don't understand how to change the password validation so I don't need a non letter or digit character.
All help greatly appreciated, thank you.
Bonus: What does the {0} and {2} mean? Thank you.
In Startup.cs where you add the Identity Service you can add options for password validation:
services.AddIdentity<ApplicationUser, IdentityRole>(Configuration,
options =>
options.Password = new PasswordOptions
{
RequireDigit = true,
RequiredLength = 6,
RequireLowercase = true,
RequireUppercase = true,
RequireNonLetterOrDigit = false
})
[...];
If you are using one of the ASP.NET template applications and have selected Authentication as 'Individual User Accounts' you will find the password options in a IdentityConfig.cs file in the App_Start folder in your application. Here you can change the password options as follows to turn off all requirements except the password length:
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = false,
RequireUppercase = false,
};
I have read lots of other posts/discussions regarding this error and have not found a clear answer.
I have customised ASP.NET Identity to store FirstName and Country as well as username/password/email address, and I'm now having issues actually storing this within the generated tables within my database.
I have already enabled migrations, added a migration and updated the database to reflect the 2 additional fields within my Identity.
Error at IdentityResult result = manager.Create(user, model.Password);
$exception {"The entity type ApplicationUser is not part of the model for the current context."} System.Exception {System.InvalidOperationException}
web.config:
<connectionStrings>
<remove name="DefaultConnection" />
<add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=WIN8-SUNEETAGU\SQLSERVER;Initial Catalog=UnderConstruction;Integrated Security=True" />
</connectionStrings>
AuthenticationModels.cs
namespace UnderConstruction.Models
{
public class AuthenticationModels
{
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string Country { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<UnderConstruction.Models.AuthenticationModels.ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{}
}
public class RegisterModel
{
[Required]
[StringLength(10, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 5)]
[Display(Name = "Username")]
public string Username { get; set; }
[Required]
[StringLength(10, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 4)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Required]
[StringLength(10, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 4)]
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
public string ConfirmPassword { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[EmailAddress(ErrorMessage="Please enter a valid email address.")]
[Display(Name = "Email address")]
public string Email { get; set; }
[Required]
[StringLength(10, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 5)]
[Display(Name = "First name")]
public string FirstName { get; set; }
[Required]
[StringLength(50)]
[Display(Name = "Country")]
public string Country { get; set; }
}
}
}
AuthenticationController.cs
public class AuthenticationController : Controller
{
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(AuthenticationModels.RegisterModel model)
{
if (ModelState.IsValid)
{
try
{
var userStore = new UserStore<UnderConstruction.Models.AuthenticationModels.ApplicationUser>();
var manager = new UserManager<UnderConstruction.Models.AuthenticationModels.ApplicationUser>(userStore);
var user = new UnderConstruction.Models.AuthenticationModels.ApplicationUser() { UserName = model.Username, Email = model.Email, FirstName = model.FirstName, Country = model.Country };
IdentityResult result = manager.Create(user, model.Password);
return View("RegisterSuccessful");
}
catch (Exception e)
{
ModelState.AddModelError("", e);
}
}
return View("Register",model);
}
}
I'm thinking it has to do with the nested classes within AuthenticationModels.cs. I'd try moving them outside of the AuthenticationModels class. Example:
namespace UnderConstruction.Models.AuthenticationModels
{
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string Country { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<UnderConstruction.Models.AuthenticationModels.ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{}
}
public class RegisterModel
{
[Required]
[StringLength(10, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 5)]
[Display(Name = "Username")]
public string Username { get; set; }
[Required]
[StringLength(10, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 4)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Required]
[StringLength(10, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 4)]
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
public string ConfirmPassword { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[EmailAddress(ErrorMessage="Please enter a valid email address.")]
[Display(Name = "Email address")]
public string Email { get; set; }
[Required]
[StringLength(10, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 5)]
[Display(Name = "First name")]
public string FirstName { get; set; }
[Required]
[StringLength(50)]
[Display(Name = "Country")]
public string Country { get; set; }
}
}
I just moved everything into the UnderConstruction.Models.AuthenticationModels namespace, instead of having to create an instance of the AuthenticationModels class.
Maybe I've found a solution.
Check the UserManager initialization in Startup.Auth.cs to be like this
UserManagerFactory = () => new UserManager<User>(new UserStore<User>(new MyContext()));
Can somebody please help me?
I want to add more fields to account controller than is provided. I want to see these fields in a table as well. I add fields in a Register class. And I am not sure about ID field I want to use auto increment but do not know how if I do not see a table. In normal database it will do automatically. Thanks.
my
Account model:
public class ChangePasswordModel
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "Current password")]
public string OldPassword { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public class LogOnModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
public class RegisterModel
{
[Required]
public int ID { get; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[DataType(DataType.PhoneNumber)]
[Display(Name = "Phone")]
public string Phone { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "First line of address")]
public string Address { get; set; }
[DataType(DataType.Date)]
[Display(Name = "DOB => dd/mm/yyyy")]
public DateTime DateOfBirth { get; set; }
[Required]
[PostCode(ErrorMessage= "PostCode is not valid")]
[Display(Name = "Post Code")]
public string PostCode { get; set; }
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public class PostCodeAttribute : RegularExpressionAttribute
{
public PostCodeAttribute()
: base(
#"([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-
hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-
Yj-y][0-9]?[A-Za-z])))) {0,1}[0-9][A-Za-z]{2})")
{
ErrorMessage = "PostCode is invalid";
}
}
Then in AccountController I can create user which has same data fields in a table but Membership do not have this option only
Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);
You might want to consider SimpleMembership (it's the future) and using your own schema, and then using NuGet to use it with MVC 3.
This is "classic" ASP.NET but should help
http://www.asp.net/web-forms/tutorials/security/membership/storing-additional-user-information-cs
(From here adding more fields to registration form using membership on MySql and MVC 3)
In an ASP.NET MVC 4 app, the LocalPasswordModel class (in Models\AccountModels.cs) looks like this:
public class LocalPasswordModel
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "Current password")]
public string OldPassword { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
The above code contains two substitution arguments in the ErrorMessage string:
ErrorMessage = "The {0} must be at least {2} characters long."
Can someone tell me where the values that get substituted into that string come from? More generally, is there anything approximating official documentation that describes how parameter substitution works in this context?
For StringLengthAttribute, the message string can take 3 arguments:
{0} Property name
{1} Maximum length
{2} Minimum length
These parameters unfortunately do not seem to be well documented. The values are passed in from each validation attribute's FormatErrorMessage attribute. For example, using .NET Reflector, here is that method from StringLengthAttribute:
public override string FormatErrorMessage(string name)
{
EnsureLegalLengths();
string format = ((this.MinimumLength != 0) && !base.CustomErrorMessageSet) ? DataAnnotationsResources.StringLengthAttribute_ValidationErrorIncludingMinimum : base.ErrorMessageString;
return String.Format(CultureInfo.CurrentCulture, format, new object[] { name, MaximumLength, MinimumLength });
}
It is safe to assume that this will never change because that would break just about every app that uses it.