Click here to Skip to main content
15,885,546 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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.

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:
C#
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; }
}
C#
[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[^].
 
Share this answer
 
Comments
Karthik_Mahalingam 10-Aug-17 23:27pm    
5
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=:)
 
Share this answer
 
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, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900