Click here to Skip to main content
14,244,068 members
Rate this:
Please Sign up or sign in to vote.
this is my Users Model:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;

namespace Models
{
    public class Users
    {
        [Key]
        public int UserID { get; set; }

        [Required]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }

        [Required]
        [Display(Name = "First Name")]
        public string FirstName { 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; }

        
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Compare("Password")]
        [NotMapped]
        public string ConfirmPassword { get; set; }

        public string PhoneNumber { get; set; }

        [DataType(DataType.DateTime)]
        [Required]
        public DateTime RegistrationDate { get; set; }

       
       
    }



This is my Login action:

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Login(Users user)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    var errors = ModelState.Values.SelectMany(v => v.Errors);
                    CarDBContext db = new CarDBContext();
                    var getUser = db.Users.Single(p => p.Email == user.Email && p.Password == user.Password);
                    if (getUser != null)
                    {
                        Session["Usr_ID"] = user.UserID.ToString();
                        Session["Email"] = user.Email.ToString();
                        Session["UserName"] = user.FirstName.ToString() + " " + user.LastName.ToString();
                        return RedirectToAction("Index", "Home");
                    }
                    else
                    {
                        ModelState.AddModelError("", "Username or Password does not match.");
                    }
                }
            }
            catch (Exception ex)
            {
                return View("Error", new HandleErrorInfo(ex, "", ""));
            }

            return View();
        }


This is my Create user action that works properly:
[HttpPost]
     public ActionResult CreateUser(Users user)
     {

           if (ModelState.IsValid)
         {
             bool Success = IsUserEmailExist(user.Email);

             if (Success == false)
             {
                 db.Users.Add(user);
                 db.SaveChanges();
                 return RedirectToAction("Index","Home");
             }

             else
             {
                 string err = "The user already exists.";
                 ViewBag.ErrMessage = err;
                 return View();
             }
         }
         return View(user);
     }


What I have tried:

I dont know why my create user is working properly but my login doesnt. Modelstate.isvalid in the login actionresult always is false.
How can I write it with ViewModel?
Posted
Updated 18-Aug-17 7:13am
Comments
maysam_p82 10-Aug-17 14:40pm
   
what do you mean?
Richard Deeming 10-Aug-17 14:47pm
   
If you query your database, you will see your users' passwords in plain text. For example:
Username: jo.bloggs@test.local
Password: 1L0veS3cureP@ssw0rds!

That's a serious security breach waiting to happen. You should only ever store a salted hash of the password, using a unique salt for each record. For example:
Username: jo.bloggs@test.local
Salt: 3E800.ABTx519WS9P64
HashedPassword: PHTcY/6cO+nVh+OXMlkgDZiGjPxjnMClHcNPkARZDdv9iYSRNv7Jw==

When the user tries to log in, you retrieve the salt, append it to the password they've entered, calculate the hash of that, and compare it to the stored hash of the password. If it matches, then the password is correct. If not, then the password is wrong.

You should NEVER be able to see the user's actual password.
maysam_p82 10-Aug-17 14:55pm
   
But I never used any hash algorithm in my application
Richard Deeming 10-Aug-17 14:56pm
   
Exactly my point. You haven't used one. You're storing passwords in plain text.

You need to use a secure hash algorithm to store your passwords securely.
maysam_p82 10-Aug-17 14:57pm
   
Does MVC note that if the password was not hash, then it doesnt allow the Modelstate.Isvalid being true?
Richard Deeming 10-Aug-17 14:58pm
   
No, unfortunately, MVC does not yet force you to write secure code. You can introduce as many critical security failures into your code as you want.
Rate this:
Please Sign up or sign in to vote.

Solution 1

You're getting validation errors because the user isn't entering every single field from the Users class when they log in. They're only entering their email and password. The other required fields will be blank.

Create a view-model for the login action:
public class LoginViewModel
{
    [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; }
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel user)
{
   ...
}

HOWEVER, as I mentioned in the comments, you should NEVER store passwords in plain text. Only ever store a salted hash of the password, using a unique salt for each record.

Secure Password Authentication Explained Simply[^]
Salted Password Hashing - Doing it Right[^]

And why are you re-inventing the wheel? ASP.NET has several perfectly good authentication systems built-in - for example, ASP.NET Identity[^].
   
Comments
Karthik_Mahalingam 10-Aug-17 23:27pm
   
5
Rate this:
Please Sign up or sign in to vote.

Solution 2

Hi,
The problem is in the your Users model that means when you submit the login button model validation validate all the validation field that are in User model but you are passing only user name and password.
So you need to create new model for Login.

Step-1)
public class LoginViewModel
{
[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; }
}

Step-2)

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel user)
{
if (ModelState.IsValid)
{
....
}
}

I hope this is working for you
Happy Coding=:)
   
Comments
Richard Deeming 18-Aug-17 13:36pm
   
That's what I said last week[^]!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100