1
votes

Following is my model class for User,

public class User
{
    [System.ComponentModel.DataAnnotations.Key]
    public int UserId { get; set; }
    public Int16 RoleID { get; set; }
    [DisplayName("First Name :")]
    public string FirstName { get; set; }
    [DisplayName("Last Name :")]
    public string LastName { get; set; }

    [DisplayName("Email :")]
    [Required(ErrorMessage = "Email is required")]
    [EmailAddress(ErrorMessage = "Invalid Email Address")]
    public string Email { get; set; }

    [DataType(DataType.Password)]
    [Required(ErrorMessage = "Password is required")]
    [DisplayName("Password :")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Compare("Password")]
    [Required(ErrorMessage = "Confirm password is required")]
    [DisplayName("Confirm Password :")]
    public string CPassword { get; set; }
}

Following code is in AccountController

 [HttpPost]
 [AllowAnonymous]
 [ValidateAntiForgeryToken]
 public ActionResult Login(User model, string returnUrl)
 {
      if(ModelState.IsValid) //This turns out to be always false
 }

This goes to Login.cshtml

@using (Html.BeginForm())
{
 @Html.AntiForgeryToken()
 @Html.ValidationSummary(true)
 <fieldset class="cf addForm">
     @Html.LabelFor(model => model.Email)
     @Html.TextBoxFor(model => model.Email, new { @class = "wd293 inputtext" })
     @Html.ValidationMessageFor(model => model.Email)
     @Html.LabelFor(model => model.Password)
     @Html.PasswordFor(model => model.Password, new { @class = "wd293 inputtext" })
     @Html.ValidationMessageFor(model => model.Password)
     <div class="cf signBtn">
        <input type="submit" value="Sign in" class="pageBtn alignleft savebtn" />
     </div>
 </fieldset>
 }

Above model class should work fine for Register form i.e. where all details are required as mentioned e.g. Email/Password/ConfirmPassword

But for Login Form where only Email and Password would be required field so in that case ModelState.IsValid is always giving false.

I am in a dilemma what should be the solution, create another model class ? like for Login form there would be another model UserLoginViewModel which would have only 2 property email/password and for Register form UserRegisterViewModel which would have all required porperty ?

Please bear with me, if this sounds silly as I am fairly new to MVC4. Please let me know if further code is needed as well.

EDIT

public class MyDBContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Category> Categories { get; set; } // It has CategoryID,CategoryName properties
}

Above is my db context class, for saving Category in database I write following code,

 new MyDBContext().Categories.Add(category);

So let say I created new class as UserRegisterViewModel with all the attribute required for register form, in that case I need to convert this UserRegisterViewModel to User again, will this be okay or will be adding memory overhead ?

Conversion would be like

 User newUser = new User(); //Assign all the properties from UserRegisterViewModel to this and save 
 new MyDBContext().Users.Add(newUser);

Please help.

3
Spin up a new MVC Internet project - it includes model/view/controller code for account management. See how MS does it.Sam Axe
I checked the implementation but in that they have used built in mechanism for authentication which may have internal database, in my case I have configured User table in the database. Please check updated question.Ani Shroff
If you use different view models then yes, need to have convertsion method in both (i someimes put it into model as Save(User u)). As an option, you can try AutoMapper (memory overhead as well, but invisibe :). If you derive models then you can use Save() method overrides.LINQ2Vodka
@jim can you please provide any links or demo for this as I am new to all this, or you can give answer as well. ThanksAni Shroff
@AniShroff i just meant that instead of assigning user properties in the controller you can do it in the view model's method like Save() (it should save model's properties into User entity).LINQ2Vodka

3 Answers

2
votes

You should have one class per view in this case. If You create a MVC project from the internet template in Visual Studio this classes/models are generated by default. You could use inheritance if you want. However, there are some possibilities to avoid multiple models, but I think it's cleaner and faster to have one model per view.

0
votes

Try to \remove required field attribute from email address

 [EmailAddress(ErrorMessage = "Invalid Email Address")]

try this , it will work or no ? is your model valid Now ?

0
votes

It turns out like we can also validate specific property and check ModelState with following code as well,

//Instead of this - which checks all attributes of model class
if (ModelState.IsValid)

Changed to this

//This will only verify against email/password property only so other property are ignored
if (ModelState.IsValidField("Email") && ModelState.IsValidField("Password")) 

Changing the code of the login with above and it worked.

Thank you all for your support.