I have been learning asp.net mvc for a while now and I am coming to grips with using the entity framework,
I have the following Model
[Table("User")]
public partial class User
{
// [ConcurrencyCheck]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Key]
public int Id { get; set; }
[Required]
[Display(Name = "User Name")]
[Remote("IsUserNameAvailable", "User", ErrorMessage = "User name already Exists.")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(150, MinimumLength = 6)]
[Display(Name = "Password")]
public string Password { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string Surname { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email")]
[Remote("IsEmailAvailable", "User", ErrorMessage = "Email Address Already Exists.")]
public string Email { get; set; }
}
This all works fine when I register a user. But my problem is that I tried Doing something like this for login
[Table("User")]
public partial class Login
{
// [ConcurrencyCheck]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Key]
public int Id { get; set; }
[Required]
[Display(Name = "User Name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(150, MinimumLength = 6)]
[Display(Name = "Password")]
public string Password { get; set; }
}
The reason I wanted this was so that I can use a model that would not have to use the remote Attribute as I wouldn't be checking if the username exists
The error I get when I do this says that I cannot use separate entities for the same table. I am trying to get around not triggering the remote attribute for the login part.
Has anyone come across this?
Thanks,
remove access modifier partial
and
[Table("User")] ,[Key]
attributes
Related
In ASP.NET Core 6/7 MVC, we have classes like this. Model is user in view. How to not have validation for credentials field and only have validation for fullname and position (as this is what the user is allowed to edit)? Thanks.
Configuration: project properties are
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>disable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
public class User
{
public User()
{
Credentials = new UserCredentials();
}
[Required]
[Display(Name = "Full Name")]
[StringLength(80)]
public string FullName { get; set; }
[Required]
[Display(Name = "Position")]
[StringLength(80)]
public string Position { get; set; }
public UserCredentials? Credentials { get; set; }
}
Now, UserCredentials class looks like this:
public class UserCredentials
{
public UserCredentials()
{
Username = string.Empty;
Password = string.Empty;
}
[Required]
[Display(Name = "User Name")]
[StringLength(20)]
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(20, MinimumLength = 6, ErrorMessage = "The {0} must be between {2} and {1} characters long.")]
public string Password { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Re-enter Password")]
[Compare("Password", ErrorMessage = "Passwords do not match.")]
public string ComparePassword { get; set; }
}
Validating the properties of UserCredentials couldn't be avoided,but in MVC project,you could try to remove them from ModelState:
foreach(var prop in typeof(UserCredentials).GetProperties())
{
var propname = "Credentials." + prop.Name;
ModelState.Remove(propname);
}
Result:
I can't build Identity on a user table already exist and I could not modify the user table within Identity
I created the models and then I generated Controls and Views.
https://imgur.com/Q6yhKgZ.png
Then I try to create a new identity through add new scaffolded item, but I could not use the already existing user table
https://imgur.com/V5YCuyz.png
And I also tried to create a new project and create the Identity first and then modify the Identity user table by adding some columns and then create my tables on the same context, but I will not find the user model to modify it and create the relationships with the other entities.
[Table("User")]
public class User
{
[Key]
public int Id { get; set; }
[Required]
[Display(Name = "Name")]
[DataType(DataType.Text)]
public string Name { get; set; }
[Required]
[Display(Name = "Phone Number")]
[DataType(DataType.PhoneNumber)]
public string Phone { get; set; }
[Required]
[Display(Name = "Email Address")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Required]
[Display(Name = "Password")]
[DataType(DataType.Password)]
[StringLength(20, MinimumLength = 6)]
public string Password { get; set; }
[Required]
[Display(Name = "Confirm Password")]
[DataType(DataType.Password)]
[Compare("Password", ErrorMessage = "Confirm password doesn't match, Type again !")]
[NotMapped]
public string ConfirmPassword { get; set; }
[Required]
[Display(Name = "Gender")]
[DataType(DataType.Text)]
public string Gender { get; set; }
[Required]
[Display(Name = "Birth Date")]
[DataType(DataType.Date)]
[CustomDate(ErrorMessage = "Use Correct Birthdate")]
public DateTime BirthDate { get; set; }
public bool Eanble { get; set; }
public string Permissions { get; set; }
[DataType(DataType.DateTime)]
public DateTime CreateAt { get; set; }
[DataType(DataType.DateTime)]
public DateTime UpdateAt { get; set; }
[InverseProperty("Owner")]
public List<Article> Articles { get; set; }
[InverseProperty("Owner")]
public List<Consultation> Consultations { get; set; }
[InverseProperty("Owner")]
public List<ConsultationComment> ConsultationComments { get; set; }
}
You are taking the wrong approach.
In order to add your own custom properties to the user you should create a class which derives from Microsoft.AspNetCore.Identity.IdentityUser. There you can add your own custom properties which would be added to the table. Here is how you can do it:
// using Microsoft.AspNetCore.Identity; is needed
public class ApplicationUser : IdentityUser
{
public int Age { get; set; }
}
Now you should create a class which derives from IdentityDbContext:
public class AppIdentityDbContext : IdentityDbContext<ApplicationUser>
{
public AppIdentityDbContext(DbContextOptions<AppIdentityDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
This is basically a DbContext with 2 DbSets that Identity will use.
Then go to your Startup.cs and add the following line inside ConfigureServices:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<AppIdentityDbContext>();
Now you can build your project and see the changes applied to your database. You can not remove Identity properties, but you can add your own.
The question I had was how are models supposed to be used? I don't think I am using them correctly. Whenever I make a change to the database (user table, in this case) and rebuild the model, my changes get erased and I end up making the changes again. The changes made are adding attributes and also another column(ConfirmPassword).
Edit: I am using EF 5
This is the model that was created by the database:
using System;
using System.Collections.Generic;
public partial class User
{
public User()
{
this.Documents = new HashSet<Document>();
}
public int UserId { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string Grade { get; set; }
}
With my changes:
using System;
using System.Collections.Generic;
using CompareObsolete = System.Web.Mvc.CompareAttribute;
public partial class User
{
public User()
{
this.Documents = new HashSet<Document>();
}
[Key]
public int UserId { get; set; }
[Required]
[StringLength(15, MinimumLength = 3)]
[Display(Name = "Username*: ")]
public string Username { get; set; }
[Required]
[EmailAddress]
[StringLength(25)]
[Display(Name = "Email Address*: ")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(50, MinimumLength = 4)]
[Display(Name = "Password*: ")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm Password*: ")]
[CompareObsolete("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
[Display(Name = "Your Grade*: ")]
public string Grade { get; set; }
}
1. Create UserMetaData Class
public class UserMetaData
{
[Key]
public int UserId { get; set; }
[Required]
[StringLength(15, MinimumLength = 3)]
[Display(Name = "Username*: ")]
public string Username { get; set; }
[Required]
[EmailAddress]
[StringLength(25)]
[Display(Name = "Email Address*: ")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
[StringLength(50, MinimumLength = 4)]
[Display(Name = "Password*: ")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm Password*: ")]
[CompareObsolete("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
[Display(Name = "Your Grade*: ")]
public string Grade { get; set; }
}
2. Create new partial class in new .cs file and assign metadata class to there by using MetadataType attribute to it.
[MetadataType(typeof(UserMetaData))] // assign type of your metadata here.
public partial class User
{
}
I would like to ask some help to figure out whats happening to my Login page.
I have a class named User.cs generated by EF
public partial class User
{
public User()
{
this.PersonnelInfo = new HashSet<PersonnelInfo>();
}
public int UserId { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public int RoleId { get; set; }
public int AccountId { get; set; }
public virtual ICollection<PersonnelInfo> PersonnelInfo { get; set; }
public virtual Role Role { get; set; }
public virtual Account Account { get; set; }
}
To add a validation to those properties I add a new class named UserMd.cs
[MetadataType(typeof(UserMetadata))]
public partial class User
{
}
public class UserMetadata
{
public int UserId { get; set; }
[Display(Name = "Username")]
[Required(ErrorMessage = "Username is required.")]
public string Username { get; set; }
[Display(Name = "Password")]
[Required(ErrorMessage = "Password is required.")]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Role")]
[Required(ErrorMessage = "Role is required.")]
public int RoleId { get; set; }
[Display(Name = "Client ID")]
[Required(ErrorMessage = "Client ID is required.")]
public int AccountId { get; set; }
public virtual ICollection<PersonnelInfo> PersonnelInfo { get; set; }
public virtual Role Role { get; set; }
public virtual Account Account { get; set; }
}
What I wanted to do is to extend my User class properties and base on my research I can extend my User class by adding additional partial class so I create UserPropertyExtended.cs
public partial class User
{
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation do not match.")]
public string ConfirmPassword { get; set; }
}
My problem occured when I add validation to ConfirmPassword property.
I cannot Login to my application.
If I remove the validation everything is fine.
I don't want to add another column to my table that's why I extend my class User.
Hope you can help me.
Thank you.
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?