Particular field getting NULL after form post - c#

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"
}

Related

How do I send data to the pre-generated Asp.net database?

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);

MVC5, Entity Framework, Custom registration with encryption

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.

Save additional profile data during "Register" in ASP.Net Identity (MVC)

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);
}
}

Extend another class to make custom class type HttpContext.User

I am making a mock social media app in Visual Studio 2013, using c#, asp.net-mvc5, and entity framework 6. I am trying to add custom user authentication
I have implemented the authentication in the web.config:
<authentication mode="Forms">
<forms loginUrl="~/AppUsers/Login" timeout="3000" />
</authentication>
and made sure that the ActionResult creates a cookie on login
[HttpPost]
public ActionResult Login(string userName, string password)
{
AppUser user = null;
if (db.AppUser.Any(m => m.UserName == userName)) {
user = db.AppUser.Where(m => m.UserName == userName).First();
if (user.Password == password) {
FormsAuthentication.SetAuthCookie(userName, true);
return RedirectToAction("AppUserProfile", new { id = user.Id });
}
}
return RedirectToAction("Login", new { message = "Invalid Password" });
}
But I am now stuck, whenever I try to check if HttpContext.User.Identity.IsAuthenticated, I get an error that says:
"An object reference is required for the non-static field, method, or property 'System.Web.HttpContext.User.get'"
Do I need to make my AppUser class extend an HttpContext class to make this error go away, or do I have to rewrite the whole class as it is?
public class AppUser
{
[Key]
public int Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
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]
[EmailAddress]
[Display(Name = "Email")]
public string EmailAddress { get; set; }
public virtual ICollection<UserPost> UserPosts { get; set; }
}
Making
HttpContext.User.Identity.IsAuthenticated
into
HttpContext.Current.User.Identity.IsAuthenticated
fixed the issue for me

View Model Property of particular type allow null in Form Post

I have this Model:
public class RegisterModel
{
[Required(ErrorMessage="Username is required")]
[StringLength(50)]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required(ErrorMessage = "Password is required")]
[StringLength(15, 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(ErrorMessage = "Email address is required")]
[DataType(DataType.EmailAddress), RegularExpression(#"\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*", ErrorMessage = "Please enter a valid email address.")]
[StringLength(100)]
public string Email { get; set; }
public RegisterViewModel RegisterVm { get; set; }
public Resume Resume { get; set; }
public Availability Availability { get; set; }
public PostRequirements PostReq { get; set; }
}
In form post action i am checking if model is valid continue else not, what i want is if PostReq is null in that case ModelState Validity can be true because in some case it will be null and ifs null i dont want to be checking it for validating.
Currently if it null, ModelState is invalid.
How can i do it?
I know for long, int etc we can make them nullable, but how to do on custom class type?

Categories