I am using Visual Studio 2015. I would like to add a first and last name to the already pre-generated Asp.net database. These columns are in the database. I have added on to the RegisterViewModel...
public class RegisterViewModel
{
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[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 = "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; }
}
And here is my controller, which I have barely modified...
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
//string EncodedResponse = Request.Form["g-Recaptcha-Response"];
//bool IsCaptchaValid=(ReCaptcha.Validate(EncodedResponse)=="True" ? true: false);
//if (IsCaptchaValid)
//{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
user.FirstName = model.FirstName;
user.LastName = model.LastName;
etc... I'm not sure why FirstName and LastName are not getting sent to the database. I thought this was the way to do it, and I have seen other ways, but I am not sure. Once I understand this, and get it to work I should be fine. Thank you.
Change your controller to do this:
var user = new ApplicationUser { UserName = model.Email, Email = model.Email, FirstName = model.FirstName, LastName = model.LastName };
var result = await UserManager.CreateAsync(user, model.Password);
Related
I am trying to learn to use Authentication & Identity Security in MVC and Entity Framework and having some difficulty.
I am working on a University Web App and the issue I am having is connecting the new Users who will be registering in the App as different roles like Students or Instructor. I have created 3 roles already in my Seed method, Admin, Student, and Instructor.
How can I write the Register method in the AccountController to connect the Student table and the ApplicationUser table?
Or like when a Student logs in, he is only able to see his account, not the list of students in the Students page?
I created a Foreign Key with the ApplicationUser table and the Person table (Student and Instructor tables inherit from Person table).
public abstract class Person
{
public int ID {get; set;}
[ForeignKey("ApplicationUser")]
public string ApplicationUserId { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
AccountController.cs
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email };
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
//Assign Role to User
await this.UserManager.AddToRoleAsync(user.Id, model.UserRoles);
return RedirectToAction("Index", "Home");
}
ViewBag.Name = new SelectList(context.Roles.Where(u => !u.Name.Contains("Admin"))
.ToList(), "Name", "Name");
AddErrors(result);
}
// Register Student
RegisterViewModel
public class RegisterViewModel
{
[Required]
[Display(Name = "UserRoles")]
public string UserRoles { get; set; }
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
//[Required]
[Display(Name = "Username")]
public string UserName { 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; }
}
Currently, a student user can see everyone, but I want the student to see only his account information. Note everyone's info.
Configuration.cs (Seed method)
protected override void Seed(SchoolContext context)
{
var students = new List<Student>
{
new Student { FirstMidName = "Carson", LastName = "Alexander",
EnrollmentDate = DateTime.Parse("2010-09-01") },
new Student { FirstMidName = "Meredith", LastName = "Alonso",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Arturo", LastName = "Anand",
EnrollmentDate = DateTime.Parse("2013-09-01") },
new Student { FirstMidName = "Gytis", LastName = "Barzdukas",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Yan", LastName = "Li",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Peggy", LastName = "Justice",
EnrollmentDate = DateTime.Parse("2011-09-01") },
new Student { FirstMidName = "Laura", LastName = "Norman",
EnrollmentDate = DateTime.Parse("2013-09-01") },
new Student { FirstMidName = "Nino", LastName = "Olivetto",
EnrollmentDate = DateTime.Parse("2005-09-01") }
};
students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s));
context.SaveChanges();
//Adding users
//if (!context.Users.Any(u => u.UserName == "Car"))
//{
// var store = new UserStore<ApplicationUser>(context);
// var manager = new UserManager<ApplicationUser>(store);
// var user = new ApplicationUser { UserName = "sampleTwo#email.com", Email = "sampleTwo#email.com" };
// manager.Create(user, "password123");
//}
I have googled a lot, but was not able to come up with a customized register method to work with different tables. Any assistance will be much helpful.
You can alter your SQL hit based on user role.
var whereClause = "";
if (User.Roll = "Student")
{
whereClause = "WHERE USER_NAME = '" + User.Name + "'";
}
sqlQuery = "SELECT .... " + whereClause;
If the user is not an Admin, only their record will be returned.
I'm new to .Net and I need your help. I'm using code first approach for my project and I'm trying to build custom register/login with encryption. By some reason I cannot save the user in my database when trying to encrypt the password. Saving the user in the database works when I remove the 2 lines for encryption and salting. Here is my User model:
public class User
{
[Key]
public int UserId { get; set; }
[Required(ErrorMessage = "First Name is required !")]
[Display(Name = "First Name: ")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Last Name is required !")]
[Display(Name = "Last Name: ")]
public string LastName { get; set; }
[Required(ErrorMessage = "Email is required !")]
[EmailAddress]
[StringLength(50)]
[RegularExpression(#"^([\w\.\-]+)#([\w\-]+)((\.(\w){2,3})+)$", ErrorMessage = "Please enter valid email")]
[Display(Name = "Email Address: ")]
public string Email { get; set; }
[StringLength(50)]
[Display(Name = "Company Name: ")]
public string CompanyName { get; set; }
[Required(ErrorMessage = "Password is required !")]
[DataType(DataType.Password)]
[Display(Name = "Password: ")]
public string Password { get; set; }
[NotMapped]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "Passwords don't match !")]
public string ConfirmPassword { get; set; }
public string PasswordSalt { get; set; }
public int AdminCode { get; set; }
}
And here is my Register method in my controller:
[HttpPost]
public ActionResult Register(Models.User user)
{
if (ModelState.IsValid)
{
using (AppContext db = new AppContext())
{
var crypto = new SimpleCrypto.PBKDF2();
var encrypPass = crypto.Compute(user.Password);
//var newUser = db.Users.Create();
//newUser.FirstName = user.FirstName;
//newUser.LastName = user.LastName;
//newUser.Email = user.Email;
//newUser.CompanyName = user.CompanyName;
//newUser.Password = encrypPass;
//newUser.PasswordSalt = crypto.Salt;
//newUser.AdminCode = 0;
user.Password = encrypPass;
user.PasswordSalt = crypto.Salt;
db.Users.Add(user);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "Data is not correct");
}
return View();
}
Here is my table.. When trying to encrypt I get Error "Validation failed for one or more entities.", but I have no idea what validation is failing. I've checked my DB table and the User model and I don't see the problem. I've really tried to figure it out by my own, but I can't! Any ideas what am I missing ? Thanks in advance.
Here Iam Trying to Register A user Using REST Using Xamarin.forms
but everry Time I Post The Httpclient I returns This Error
System.Net.Http.HttpRequestException: 400 (Bad Request)
I Tried Every thig But Always The same Error Here Is MY RegisterService Class
private const string WebServiceUrl = "http://MyIP:49932/api/Account/Register";
public async Task Register(string username, string password, string confirmPassword)
{
RegisterModel model = new RegisterModel
{
ConfirmPassword = confirmPassword,
Password = password,
Email = username
};
var httpClient = new HttpClient(new NativeMessageHandler());
var json = JsonConvert.SerializeObject(model);
HttpContent httpContent = new StringContent(json);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
try
{
var result = await httpClient.PostAsync(WebServiceUrl, httpContent);
result.EnsureSuccessStatusCode();
}
catch(Exception ex)
{
}
}
}
}
and this is the Api From AccountController
// POST api/Account/Register
[AllowAnonymous]
[Route("Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
//string UserName, string Password,string ConfirmPassword
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
user.RegistrationDate = DateTime.Now;
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
return Ok();
}
Edit*
The Registermodel
public class RegisterModel
{
public string Email { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
}
The RegisterBindingModel
public class RegisterBindingModel
{
[Required]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 3)]
[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; }
}
Please Anyone Help ME Ihave Been Stuck For A Week Now
Thanx IN Advance
I need to store additional information during user registration such as: First Name, Last Name and etc.
My question has two parts:
How can I save my additional information during Register?
My current method throws error:
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
I have already checked "Watch" inside VS and also used try-catch but it didn't help.
Thanks in advance for your help!
IdentityModels.cs
public class ApplicationIdentityAccount : IdentityUser
{
public virtual ICollection<AccountProfile> AccountProfiles { get; set; }
}
public class AccountProfile
{
[Key]
public string AccountProfileID { get; set; }
[DisplayName("First Name")]
[StringLength(50)]
[Required(ErrorMessage = "First name is required")]
public string FirstName { get; set; }
[DisplayName("Middle Name")]
[StringLength(50)]
public string MiddleName { get; set; }
[DisplayName("Last Name")]
[StringLength(50)]
[Required(ErrorMessage = "Last name is required")]
public string LastName { get; set; }
public string UserId { get; set; }
[ForeignKey("UserId")]
public virtual ApplicationIdentityAccount User { get; set; }
}
public class ApplicationIdentityDbContext : IdentityDbContext<ApplicationIdentityAccount>
{
public ApplicationIdentityDbContext()
: base("ApplicationIdentity", throwIfV1Schema: false)
{
}
public static ApplicationIdentityDbContext Create()
{
return new ApplicationIdentityDbContext();
}
public System.Data.Entity.DbSet<AccountProfile> AccountProfile { get; set; }
}
AccountViewModels.cs > RegisterViewModel
public class RegisterViewModel
{
[Required]
[Display(Name = "Username")]
public string UserName { get; set; }
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[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 = "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; }
}
AccountController.cs
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationIdentityAccount
{
UserName = model.UserName,
Email = model.Email,
AccountProfile = new[] {new AccountProfile()
{
FirstName = model.FirstName,
LastName = model.LastName
}}
};
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking here");
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
I know that I should place FirstName and LastName inside:
var user = new ApplicationIdentityAccount
{
UserName = model.UserName,
Email = model.Email,
};
Since your question has two parts:
Your method for storing additional information is correct
You can't proceed unless you see the actual error, in order to see the details you need to add this where you create the user.
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
// Retrieve the error messages as a list of strings.
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
// Join the list to a single string.
var fullErrorMessage = string.Join("; ", errorMessages);
// Combine the original exception message with the new one.
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
// Throw a new DbEntityValidationException with the improved exception message.
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
}
Hi I'm using Angulajs as front end and ASP.NET WebAPI as backend.
This is my Model class:
public class UserModel
{
[Required]
[Display(Name = "User name")]
public string UserName { 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; }
[Required]
[StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 7)]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[Display(Name = "Phone")]
public string PhoneNumber { get; set; }
}
Controller:
// POST api/Account/Register
[AllowAnonymous]
[Route("Register")]
public async Task<IHttpActionResult> Register(UserModel userModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
IdentityResult result = await _repo.RegisterUser(userModel);
IHttpActionResult errorResult = GetErrorResult(result);
if (errorResult != null)
{
return errorResult;
}
return Ok();
}
This is my Angular Service:
var _saveRegistration = function (registration) {
return $http.post('http://localhost:26264/api/account/register', registration).then(function (response) {
return response;
});
};
I'm sending payload
P.S This is made up payload
registration:{
userName:"UserName",
email: "eamil#emal.com",
password:"password",
confirmPassword:"password",
phone: "9898989898"
}
When I debug I see all the values in payload but when I set debugger at API Controller "register" method field "PhoneNumber" is null.
I don't know what wrong I'm doing, please help
Change phone to phoneNumber
registration:{
userName:"UserName",
email: "eamil#emal.com",
password:"password",
confirmPassword:"password",
phoneNumber: "9898989898"
}