I am trying to do two things here:
1. Adding an email field to the (default)UserProfile table. Works like a charm. Users can register both a username and email.
2. Change the login to use the email instead of username, this does also works like a charm.
Here is the problem. The above only works when i seperate them, as soon as I use both of them the registration process fails with the following error message:
Cannot insert the value NULL into column 'UserName', table 'opdb.dbo.UserProfile'; column does not allow nulls. INSERT fails.
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { Email = model.Email
});
WebSecurity.Login(model.Email, model.Password);
I am more or less following the guide found here, In the comments section I see others having the same problem, however, the solution is not to set the UserName field to allow nulls as stated in the replies.
The strange thing is that everything works as long as I don't use both together. Any ideas? This drives me crazy!
Thanks in advance
Edit: Could it be the order of columns in the database? That the field used for identification needs to be the first column in the table? So if I want email as ident that need to be the first column in the table?
It is not the column order. I think you haven't set your WebSecurity.InitializeDatabaseConnection
up properly. It sounds like when you add the email field, it is treated as the email field (and not the natural key for the users), and when you change the login to use the email, you are actually inserting the email into the UserName column?
Either way, it is simple to make work. Assuming you already have your email column in the database and you are using the standard Internet Application template, do the following:
UserProfile
model to add an Email
property, do the same to the RegisterModel
and change the Login
model from UserName
to Email
InitializeSimpleMembershipAttribute
to use Email instead of UserName
as the natural key for the usersAccountController
Login
and Register
actions so you capture a UserName and an Email on registration, and use the Email on loginSo, the actual changes to make are:
class UserProfile
: add the property public string Email { get; set; }
class LoginModel
: change the property name from UserName
to Email
class RegisterModel
: add the property public string Email { get; set; }
and set its attributes to Required
, set the Display(Name
etc. (max length if you want to enforce that as wellAccountController
changes
Login
method:
model.UserName
to model.Email
in the line if (ModelState.IsValid && WebSecurity.Login(model.UserName ...
Register
method:
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
to WebSecurity.CreateUserAndAccount(model.Email, model.Password, new { UserName = model.UserName });
WebSecurity.Login(model.UserName, model.Password);
to WebSecurity.Login(model.Email, model.Password);
"UserName"
to "Email"
in WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
m.UserName
to m.Email
<li>
section and change the duplicates m.UserName
to m.Email
In a vanilla Internet Application MVC 4 project, these changes will work perfectly (in a true vanilla project you may have to apply migrations if you want to use these and you aren't editing the database to add the Email column).
I am not sure if Andy Browns suggestion will work because the WebSecurity in namespace WebMatrix.WebData references will not work correctly as a result. They are specifically looking at the UserName field to perform their actions. I could be wrong, but that's my perception. If you want a separate field, create another username field (Name) and run your own code to update that to reflect to the user.
I chose to set up a registration view that renamed the UserName to User Email
<li>
@Html.Label("Email Address:")
@Html.TextBoxFor(m => m.UserName)
</li>
and then in the Login and Register model simply required the user name entered as an email format using:
[Required]
[DataType(DataType.EmailAddress)]
[EmailAddress]
[Display(Name = "UserEmail")]
public string UserName { get; set; }
Maybe too simplistic, but it works for me.
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