使用私有属性getter(用于密码)在Controller上绑定ASP.NET Core模型

问题描述 投票:0回答:1

我有这个简单的用户类和密码属性我想让getter私有(仅在内部使用 - 公开一个公共VerifyPassword方法,它将在内部执行验证并返回一个布尔值)

现在问题来自我的Controller中的路由上的模型绑定。当我尝试使用asp-for标记帮助程序指向Model.Password时,它告诉我“密码不能在此上下文中使用,因为get-accessor不可用”

我是初学者。我认为让吸气剂私有化是一个聪明的举动,以保护它免受暴露。但现在我不能在模型绑定中使用它。

所以有几个问题:这是保护密码的正确方法吗?这是使用模型绑定的正确方法吗?有关如何改进的任何建议?

这是模型:

    using System;

namespace user_signup.Models {
    public class User
    {
        private string username;
        private string email;
        private string password;

        public string Username { 
            get => username;
            set {
                if (value.Length < 5) {
                    throw new ArgumentException("Username is too short.");
                }
                if (value.Length > 15) {
                    throw new ArgumentException("Username is too long.");
                }
                username = value;
            }
        }
        public string Email {
            get => email;
            set {
                // email validation here
                email = value; 
            }
        }

        public string Password {
            // the getter is private (only accessable internally)
            private get => password;
            set {
                if (value.Length < 5) {
                    throw new ArgumentException("Password is too short.");
                } 
                if (value.Length > 15) {
                    throw new ArgumentException("Password is too long.");
                }

                password = value;
            }
        }

        // public means of verifying a password (the password itself is never exposed)
        public bool VerifyPassword(string pass) => Password.Equals(pass);


        // counter of all users that have been instantiated (prevents overlapping IDs)
        // static so it is at the Class level (can be counted globally outside of all User instances)
        private static int NextId = 0;

        // can only be set internally (private setter)
        // defaults to the CURRENT VALUE of NextId and THEN increments NextId for the next instantiation
        public int UserId { get; } = NextId++;

        // can only be set internally (private setter)
        // defaults to current DateTime in string format
        public string CreateDate { get; private set; } = DateTime.Now.ToString(); 

        // the model will be populated from form data sent in a Request
        public User() {}

        // for creating a user by other means (manually)
        public User(string u, string e, string p) {
            Username = u;
            Email = e;
            Password = p;
        }

        public override string ToString() {
            return String.Format(
                "UserId: {0}\nUsername: {1}\nEmail: {2}\n\n",
                UserId,
                Username,
                Email
            );

        }
    }
}

这是Controller(特别是Add.cshtml GET和POST处理程序)

    [HttpGet]
    public IActionResult Add() {
        VModel.User = new User();
        return View(VModel);
    }

    [HttpPost]
    public IActionResult Add(User user, string verify) {
        VModel.User = user;
        VModel.Users = Users.GetUsers();
        if (!user.VerifyPassword(verify)) {
            VModel.Errors["verify"] = "Verify password failed. Passwords do not match.";
            return View(VModel);
        }

        return View("Index", VModel);

    }

最后是Add.cshtml视图

@using user_signup.Controllers
@model UserController.ViewModel

<!DOCTYPE html>

<html>
<head>
    <title>title</title>
</head>
<body>
<div>
    <form  asp-controller="User" asp-action="Add" method="post">
        <label>Username: </label>
        <input type="text" asp-for="@Model.User.Username" required/>

        <label>Email: </label>
        <input type="text" asp-for="@Model.User.Email"/>

        <label>Password: </label>
        <input type="password" asp-for="@Model.User.Password" required/>

        <label>Verify Password: </label>
        <input type="password" name="verify" required/>

        <input type="submit" value="Sign Up"/>

    </form>
</div>
</body>
</html>
c# razor asp.net-core-mvc private model-binding
1个回答
1
投票
  • 不要将密码作为纯文本存储在数据库中
  • 使用ASP.NET Identity来管理Auth
  • 不要直接在View中使用域实体(在本例中为User),而是使用ViewModel
  • 用户Fluent Validation用于验证用户输入
© www.soinside.com 2019 - 2024. All rights reserved.