Exclude property of model in insert Entity Framework - asp.net-mvc

I get an error when inserting data into my database. My database columns are:
username, password
and I added confirmpassword to the model to extend it.
How do I get rid of the confirmpassword to insert the username and password while using the model with confirmpassword property?
My code:
BootstrapTrainingEntities db = new BootstrapTrainingEntities();
var u = new User();
u.username = user.username;
u.password = user.password;
// how to I remove or ignore the confirmPassword property when saving?
db.Users.Add(u);
db.SaveChanges();
Model
[MetadataType(typeof(metadataUser))]
public partial class User
{
public string confirmPassword { get; set; }
}
public class metadataUser
{
[Required(ErrorMessage = "Username is required", AllowEmptyStrings = false)]
[Display(Name ="Username")]
public string username { get; set; }
[Required(ErrorMessage ="Password is required", AllowEmptyStrings = false)]
[Display(Name = "Password")]
[DataType(DataType.Password)]
public string password { get; set; }
[Required(ErrorMessage ="Confirmation Password is required", AllowEmptyStrings = false)]
[Display(Name ="Confiramation Password")]
[DataType(DataType.Password)]
[Compare("password",ErrorMessage = "Password does not match")]
public string confirmPassword { get; set; }
}

This SO has three different solutions that may help you:
How not persist property EF4 code first?
Summary:
First try the DataAnnotations approach:
Make sure you include the required library. Then apply the [Not Mapped] annotation to your field in the model.
using System.ComponentModel.DataAnnotations;
[NotMapped]
public string confirmPassword { get; set; }
If this doesn't do it, try to modify your OnModelBuilding method in your dbContext. There are two options in this block. The first is to use the Ignore method.
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MetaDataUser>().Ignore(p => p.confirmPassword);
}
}
The second is to manually remap the model building and exclude your field.
Additional SO answers that may be useful:
Entity Framework Code First - How to ignore a column when saving
Exclude a field/property from the database with Entity Framework 4 & Code-First
MS Doc on how to manually map properties to db fields:
https://learn.microsoft.com/en-us/ef/core/modeling/relational/columns
Clean example of answer provided:
http://www.dotnetodyssey.com/2015/03/31/ignore-class-property-to-table-column-in-entity-framework-code-first/

I think what you need to do is add a viewmodel for the page.First of all you will have model that is generated from entity framework which might look as below.
public class User
{
public int id{get;set;}
public string username {get;set;}
public string password {get;set;}
}
So now create a viewModel for your View .This might look as below.
public class UserViewModel
{
public int id{get;set;}
[Required(ErrorMessage = "Username is required", AllowEmptyStrings = false)]
[Display(Name ="Username")]
public string username { get; set; }
[Required(ErrorMessage ="Password is required", AllowEmptyStrings = false)]
[Display(Name = "Password")]
[DataType(DataType.Password)]
public string password { get; set; }
[Required(ErrorMessage ="Confirmation Password is required", AllowEmptyStrings = false)]
[Display(Name ="Confiramation Password")]
[DataType(DataType.Password)]
[Compare("password",ErrorMessage = "Password does not match")]
public string confirmPassword { get; set; }
}
and now in your controller action method. you can do as below.
[HttpPost]
public ActionResult AddUser(UserViewModel model)
{
User user=new User();
user.username=model.username;
user.password=model.password;
db.User.Add(user);
}
Hope it helps !

Related

How to update my user account data on ASP.net MVC 5 application

I am new to the asp.net MVC 5 identity framework andI am try to do update my details directly.
Straight forward, What I want to do is to update my user information to the database.
Previously, I changed my user details by using Migrations and I use entity framework in order to generate my controller, view and model it self.
However, How do I update my user details. I have seen role methods..but I never understand, How can I do? without using role..Because,
I want to update all of user information that I needed to do it in UserManageController...
Is it possible? in a different controller and getting values directly on generated user account? How to retrieve then?
Here is my Identity Models
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
public string userFname { get; set; }
public string userLname { get; set; }
public string address { get; set; }
public string userContactNo { get; set; }
public string commercialName { get; set; }
public string commercialAddress { get; set; }
public string commercialEmail { get; set; }
public string userType { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
Here is my Registeration model
public class RegisterViewModel
{
[Required]
[Display(Name = "User First Name")]
public string userFname { get; set; }
[Required]
[Display(Name = "User Last Name")]
public string userLname { get; set; }
[Required]
[Display(Name = "User Address")]
public string address { get; set; }
[Required]
[Display(Name = "User Contact Number")]
public string userContactNo { get; set; }
[Display(Name = "Commercial Name")]
public string commercialName { get; set; }
[Display(Name = "Commercial Address")]
public string commercialAddress { get; set; }
[EmailAddress]
[Display(Name = "Commercial Email")]
public string commercialEmail { get; set; }
[Key]
[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; }
[Required]
public string userType { get; set; }
}
How I do this,
UPDATED: As he commented in my answer bellow, he want to update a list of users in the same method. So this will work.
[HttpPost]
public async Task<ActionResult> UpdateUserInfo(List<RegisterViewModel> model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var userStore = new UserStore<ApplicationUser>(new
ApplicationDbContext());
var appManager = new UserManager<ApplicationUser>(userStore);
// here you can do a foreach loop and get the email and assign new datas
foreach(var i in model)
{
var currentUser = appManager.FindByEmail(i.Email);
// here you can assign the updated values
currentUser.userFname = i.userFname;
// and rest fields are goes here
await appManager.UpdateAsync(currentUser);
}
var ctx = userStore.Context;
ctx.SaveChanges();
// now you can redirect to some other method or-else you can return
// to this view itself by returning the data
return RedirectToAction("SomeActionMethod");
}
And yes, you should have the fields in your view and there will be a #Html.BeginForm and a submit button to post your data. Or-else you can post by ajax method
Hope it helps.
Assuming that your ApplicationUser class is part of your Entity Framework DBContext, you can retrieve and update a user like so, using Entity Framework;
var userId = "user id here"; // Set a user ID that you would like to retrieve
var dbContext = new YourDbContext(); // Your entity framework DbContext
// Retrieve a user from the database
var user = dbContext.Set<ApplicationUser>().Find(userId);
// Update a property on your user
user.address = "New value";
// Save the new value to the database
dbContext.SaveChanges();
If you need the userId of the current logged in user, use:
var userId = this.User.Identity.GetUserId();
Multiple users can be retrieved and updated like this:
var dbContext = new YourDbContext();
// Get all users
var users = dbContext.Set<ApplicationUser>().ToList();
foreach (var user in users)
{
user.address = "New value";
}
// Save the new value to the database
dbContext.SaveChanges();
Entity framework will automatically track the changes to each for when you save.

I'm working on MVC 4 , when I try to insert data into user table an error occurs

I'm working on ASP.NET MVC 4, and when I try to insert data into user table an error occurs:
The best overloaded method match for 'System.Data.Entity.DbSet.Add(PHARMACY.Models.User)' has some invalid arguments E:\Testing\PHARMACY\PHARMACY\Controllers\AdminController.cs 56 21 PHARMACY
This is my controller:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult CreateUser(Createuser cu)
{
if (ModelState.IsValid)
{
using (UserDB db = new UserDB())
{
db.users.Add(cu);
db.SaveChanges();
ModelState.Clear();
cu = null;
ViewBag.Message = "User Added Sucessfully";
return View();
}
}
else
{
}
}
This is my model
[Table("User")]
public class User
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string Full_Name { get; set; }
[Required(ErrorMessage = "Please Provide Username", AllowEmptyStrings = false)]
public string Username { get; set; }
[Required(ErrorMessage = "Please provide password", AllowEmptyStrings = false)]
[DataType(System.ComponentModel.DataAnnotations.DataType.Password)]
public string Password { get; set; }
public string User_Type { get; set; }
public string Login_Status { get; set; }
}
public class Createuser
{
[Required(ErrorMessage = "Please Provide Fullname", AllowEmptyStrings = false)]
[Display(Name = "Full Name")]
public string Full_Name { get; set; }
[Required(ErrorMessage = "Please Provide Username", AllowEmptyStrings = false)]
public string Username { get; set; }
[Required(ErrorMessage = "Please provide password", AllowEmptyStrings = false)]
[DataType(System.ComponentModel.DataAnnotations.DataType.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 = "Please Select User type", AllowEmptyStrings = false)]
[Display(Name = "User Type")]
public string User_Type { get; set; }
[Required(ErrorMessage = "Please Select Login Status", AllowEmptyStrings = false)]
[Display(Name = "Login Status")]
public string Login_Status { get; set; }
}
public class UserDB : DbContext
{
public DbSet<User> users { get; set; }
}
Your db.users.Add() method accepts a User, yet you pass it a CreateUser. That won't work.
You need to map the CreateUser to a User:
var user = new User
{
Full_Name = cu.Full_Name,
...
}
db.users.Add(user);
You can not put a CreateUser into a table that expects a User. They might have the same properties etc. put they are not the same type, so no dice.
No need to "convert" your CreateUser into a User object, and store that.
You are trying to add a Createuser type to a User type.
You are doing db.users.Add(cu); when cu is of type Createuser. You'll need to do a transformation from Createuser to User first.

Using custom database in MVC 3 for user login/registration

Okay so I have a MVC project that auto generates an AccountController AcountModel and the associated views.
I created a database with 3 tables using the model first approach, and generated all the controllers/views for all the CRUD operations.
The database contains a user table with a user id, email and password.
How can I use this user table with the auto generated AccountController for user login and registration?
I will show you registration process only , refering which you can build your login/registration with custom database.
Models:
You will add your custommodel to the AccountModels.cs, So it will have following details:
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")]
[System.Web.Mvc.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]
[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")]
[System.Web.Mvc.Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public class userDetailModel
{
[Key]
public Guid UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public string city { get; set; }
public string ConfirmPassword { get; set; }
public string comapny { get; set; }
public int zip { get; set; }
}
Context:
You will add custom context to the Models as below:
public class userDetailsDBContext: DbContext
{
public DbSet<userDetailModel> details { get; set; }
}
Controller:
Now we will modify our AccountController for registration as below:
public class AccountController : Controller
{
private userDetailsDBContext db = new userDetailsDBContext();
// POST: /Account/Register
[HttpPost]
public ActionResult Register(userDetailModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
MembershipCreateStatus createStatus;
Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);
if (createStatus == MembershipCreateStatus.Success)
{
FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */);
var newuser = Membership.GetUser(model.UserName);
model.UserId =(Guid)newuser.ProviderUserKey;
db.details.Add(model);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", ErrorCodeToString(createStatus));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
}
EDIT web.config:
Finally, you will have to add the new context to the connectionstrings as below:
<connectionStrings>
<add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MembershipSample-20121105163515;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-MembershipSample-20121105163515.mdf" />
<add name="userDetailsDBContext" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MembershipSample-20121105163515;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-MembershipSample-20121105163515.mdf" />
</connectionStrings>
You can change the database name to whatever you want and put it as your convenience but put the path here correctly.
Hope you have got the idea now...
I think waht you need is to create custom membership provider. This code project article will give you aplace to start.

Asp.Net MVC 3: Compare validator on subproperties?

For the edition of my user, I've to ensure that password and the repeat password are the same. I found the "Compare" validator, but I cant make it work.
my model looks like the following:
public class UserEditionViewModel{
[Compare("User.Password")]
public String RepeatPassword{get;set;}
public User User {get;set;}
public List<Language> AvailableLanguages{get;set;}
public List<Country> AvailableCountries{get;set;}
}
and the User model:
public class User{
[Required]
public String Name{get;set;}
//lot of other properties omitted...
[RegularExpression(#"(|.*(?=.{6,})(?=.*\d)(?=.*[a-zA-Z]).*)", ErrorMessageResourceType = typeof(LocalizationResources.Views.User.Edition), ErrorMessageResourceName = "InvalidPassword")]
//And I've localization attributes
public String Password{get;set;}
}
In the view I only have something like:
#Html.PasswordFor(m=>m.User.Password)
#Html.PasswordFor(m=>m.RepeatPassword)
But I ever get this error, even if the two items are matching:
'Password repeat' and 'User.Password' do not match.
I also got this error when I'm doing the client validation.
For me the most obvious error is that it can't found the subproperty. Am I right? If yes, how to avoid this behavior. If no, what can be the problem???
A workaround would be to create another property on the UserEditionViewModel that reads and writes to the inner Userclass.
public String UserPassword
{
get
{
return User.Password;
}
set
{
User.Password = value;
}
}
And then bind your controls to that property instead, and change the [Compare("User.Password")] to [Compare("UserPassword")]. I'm not really sure if it can be done any other way short of writing your own custom validator.
I had a similar problem and ended up writing my own validator for this which turned out surprisingly complex since you can have any layer of inheritance to get to your property. If there is another solution, I'd be equally happy to know about it.
You can try this which worked for me..
In your project -> References-> right click->Manage NuGet Packages..
install DataAnnotationsExtensions package.
Then validate your model as follows:
public class Employee
{
[Required(ErrorMessage="Name field Required")]
public string name { get; set; }
[Required(ErrorMessage = "Name field Required")]
public string email { get; set; }
[Required(ErrorMessage = "Depatrment field Required")]
public string department { get; set; }
[Required(ErrorMessage = "Designation field Required")]
public string designation { get; set; }
public string phone { get; set; }
[Required(ErrorMessage = "Password field Required")]
[Display(Name="Password")]
public string password { get; set; }
[Required(ErrorMessage="Confirm password")]
[Display(Name="Re-type Password")]
[EqualToAttribute("password",ErrorMessage="Password miss-match")]
public string Re_Password { get; set; }
}
That's it

Problems with editing using a custom model

I have this data model:
public class User
{
public long UserID { get; set; }
[Required(ErrorMessage = "User name is required.")]
[MaxLength(50, ErrorMessage = "User name cannot be longer than 50 characters.")]
public string UserName { get; set; }
[Email]
[Required(ErrorMessage = "Email is required.")]
[MaxLength(100, ErrorMessage = "Email cannot be longer than 100 characters.")]
public string Email { get; set; }
[Required(ErrorMessage = "Password is required.")]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
public string Password { get; set; }
[MaxLength(150, ErrorMessage = "Full name cannot be longer than 150 characters.")]
public string FullName { get; set; }
public int UserTypeID { get; set; }
public virtual UserType UserType { get; set; }
public virtual ICollection<Page> Pages { get; set; }
}
and I'm using this model to only edit some fields (password shouldn't be editable):
public class EditUserModel
{
public long UserID { get; set; }
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Email]
[Required(ErrorMessage = "Email is required.")]
[MaxLength(100, ErrorMessage = "Email cannot be longer than 100 characters.")]
public string Email { get; set; }
[DataType(DataType.Text)]
[Display(Name = "Full name")]
[MaxLength(150, ErrorMessage = "Full name cannot be longer than 150 characters.")]
public string FullName { get; set; }
public int UserTypeID { get; set; }
public virtual UserType UserType { get; set; }
}
but I'm confused on how to pass the EditUserModel to my data context to update it. Sorry if seems elementary, but I'm really stumped.
This is the auto-generated edit action that I modified:
[IsAdministrator]
[HttpPost]
public ActionResult Edit(EditUserModel user)
{
if (ModelState.IsValid)
{
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.UserTypeID = new SelectList(db.UserTypes, "UserTypeId", "Name", user.UserTypeID);
return View(user);
}
This is the line I'm having trouble with:
db.Entry(user).State = EntityState.Modified;
The reason I created a custom class was to avoid exposing the password from the view.
This can't work because you're trying to save view model.
You could use AutoMapper to rewrite data from view model to your data model. After that you should be able to save changes.
User userModel = Mapper.Map<EditUserModel, User>(user);
userModel = // todo: get password from database
// todo: attach your model to context and save changes
I'm using Entity Framework Code First and that approach works great.

Resources